I am confused about how to declare a type for watch
as a prop. Here is an example:
// pages/FormContainer.tsx
import { useForm, useWatch } from "react-hook-form";
import FormView from "./FormView";
interface FormInputs {
firstName: string;
lastName: string;
age: number;
}
const FormContainer = () => {
const { control, register } = useForm<FormInputs>({
defaultValues: {
firstName: "Jon",
lastName: "Doe",
age: 24
}
});
const formData = useWatch({ control });
return <FormView register={register} formData={formData} />;
};
export default FormContainer;
// pages/FormView.tsx
import { UseFormReturn } from "react-hook-form";
interface Props {
register: UseFormReturn["register"];
formData: UseFormReturn["watch"];
}
const FormView = ({ formData }: Props) => {
return (
<div>
<h1>
My Name: {formData.firstName} {formData.lastName}
</h1>
<h2>I am {formData.age} years old</h2>
</div>
);
};
export default FormView;
The thing is typescript shows me an error on this formData={formData}
prop
Here I provided a sandbox to be clear on what I mean
CodePudding user response:
UseFormReturn["watch"]
will give you back the type of the watch
function itself - that is, the type of this function:
// `watch` here is of type `UseFormReturn["watch"]
const { control, register, watch } = useForm<FormInputs>({
// ...
});
For reference, the return type of this watch
function is UnpackNestedValues<TFormValues>
.
But - you're not using that function, you're using useWatch
which returns a subtly different UnpackNestedValue<DeepPartialSkipArrayKey<TFieldValues>>
. So, you could change your form type to that:
import { UnpackNestedValue, UseFormReturn, DeepPartialSkipArrayKey } from "react-hook-form";
import { FormInputs } from "./FormContainer";
interface Props {
register: UseFormReturn["register"];
formData: UnpackNestedValue<DeepPartialSkipArrayKey<FormInputs>>
}
Alternatively, since your form object (at least in this example) is very "simple" (it's just key/value pairs effectively), you could use the simpler type declaration of Partial<FormInputs>
which is functionally equivalent in this case.
Here's an updated example for you.
CodePudding user response:
I found 2 things that will improve and fix your problem.
- Use the method
watch
returned fromuseForm
instead ofuseWatch
for getting full form data. You can useuseWatch
for individual form input changes without impacting the root component's render.
// Empty watch function will return the full form data.
const formData = watch()
watch
returns the full form data, so the prop in theFormView
component will beFormInputs
.
interface Props {
register: UseFormReturn["register"];
formData: FormInputs;
}
This should fix your TS errors.