Explantion
I'm creating a dynamic input form using the FormProvider from react-hook-form.
const formMethods = useForm<TSongFormData>();
return (
<FormProvider {...formMethods}>
<SongInputForm />
</FormProvider>
)
In the SongInputForm
component I have my actual form which will have the input components which I have created for every input elements
like input
teaxtarea
and so on...
const SongForm = () => {
const { handleSubmit } = useFormContext<TSongFormData>();
return (
<form
onSubmit={handleSubmit((data) => console.log("data", data))}
>
<InputElement label="Song Name" name="name" />
<InputElement label="Author" name="author" />
<input type="submit" />
</form>
);
};
}
The InputElement
ccomponent would receive all the props
for the input
element itself and the name
prop would be a union type TSongFormDataKey
of all the keys of the form data.
interface ITextInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
name: TSongFormDataKey;
}
const InputElement = ({ name, label, ...restProps }: ITextInputProps) => {
const { register } = useFormContext<TSongFormData>();
return (
<div>
<label htmlFor={name}>{label}</label>
<input id={name} {...restProps} {...register(name)} />
</div>
);
};
Question
As of now, I have hardcoded the types TSongFormData
and TSongFormDataKey
in the InputElement
component.
But how do I pass both the types TSongFormData
and TSongFormDataKey
as generics to the InputElement
component so that I can make it dynamic and have more flexibility on the type of props passed to it??
What I'm looking for is something like this:
interface ITextInputProps<T> extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string;
name: T;
}
const InputElement = <T,K>({ name, label, ...restProps }: ITextInputProps<T>) => {
const { register } = useFormContext<K>();
return (
<div>
<label htmlFor={name}>{label}</label>
<input id={name} {...restProps} {...register(name)} />
</div>
);
};
where T
would be TSongFormData
and K
would be TSongFormDataKey
.
I've created a codesandbox if anyone wants to play with it: https://codesandbox.io/s/elastic-sanne-uz3ei8
I'm new to typescript and trying to get my head around generics, but finding it so hard.
Any help would be greatly appreciated. Thanks