Reputation: 329
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
Upvotes: 2
Views: 7952
Reputation: 96
I found 2 things that will improve and fix your problem.
watch
returned from useForm
instead of useWatch
for getting full form data. You can use useWatch
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 the FormView
component will be FormInputs
.interface Props {
register: UseFormReturn["register"];
formData: FormInputs;
}
This should fix your TS errors.
Upvotes: 2
Reputation: 6627
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.
Upvotes: 6