I've got this code how to type dynamically data param of onHandlerData function?
export interface UserFormDto {
credentials: UserCredentialsDto | null;
details: UserDetailsDto | null;
address: UserAddressDto | null;
}
const [data, setData] = useState<UserFormDto>({
credentials: null,
details: null,
address: null,
});
const onHandlerData = (
type: keyof UserFormDto,
data: UserFormDto["credentials"]
) => {
setData((data) => {
return { ...data, [type]: data };
});
};
CodePudding user response:
First, there's a problem with the implementation of onHandlerData
(not just its types), you're shadowing the data
parameter with the data
parameter in the setData
callback. You'll need a different name for that.
Once you have that, you can use a generic type parameter to handle ensuring type
and data
work together, like this:
const onHandlerData = <KeyType extends keyof UserFormDto,>(
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
type: KeyType,
// ^^^^^^^
data: UserFormDto[KeyType]
// ^^^^^^^^^^^^^^^^^^^^
) => {
setData((current) => {
return { ...current, [type]: data };
});
};
(The ,
after the generic type parameter definition is so that it works with JSX. It tells the parser that that <...>
thing isn't an element definition.)
CodePudding user response:
One way to achieve it I could think of is to use generic, like this:
const onHandlerData = <T extends keyof UserFormDTo>(
type: T,
data: UserFormDto[T]
) => {
setData((oldData) => {
return { ...oldData, [type]: data };
});
};