I'm encountering a problem while using React Hook Form with Yup for validation. I have a schema where some fields are optional, but I'm getting a type error related to the resolver.
Here's my Yup schema:
const yupSchema = yup.object({
name: yup.string()
.typeError('Name must be a string')
.required('Name is required')
.min(3, 'Name must be at least 3 characters long'),
surname: yup.string()
.matches(/^[a-zA-Z]+$/, 'Surname must contain only letters'),
age: yup.number()
.min(0, 'Age must be greater than or equal to 0')
.max(120, 'Age must be less than or equal to 120'),
});
type YupFormData = yup.InferType<typeof yupSchema>;
In this schema, age and surname are optional fields. However, I am receiving the following error when using the resolver:
Types of parameters options and options are incompatible.
Type 'ResolverOptions<{ surname?: string | undefined; age?: number | undefined; name: string; }>' is not assignable to type 'ResolverOptions<{ name: string; surname: string | undefined; age: number | undefined; }>'.
Property 'surname' is optional in type
{
surname?: string | undefined;
age?: number | undefined;
name: string;
}
but required in type
{
name: string;
surname: string | undefined;
age: number | undefined;
}
Here's how I'm using the useForm hook:
const {
control,
handleSubmit,
formState: {
errors,
},
} = useForm<YupFormData>({
resolver: yupResolver(yupSchema),
mode: 'onBlur',
});
I would appreciate any help in resolving this issue. Thank you!
What I tried:
I created a Yup validation schema with optional fields for surname and age. I then set up the useForm hook from React Hook Form, integrating the Yup schema using the yupResolver. I expected the form to validate correctly without errors, even when the optional fields were left blank.
What I was expecting:
I expected that the optional fields (surname and age) would not cause any type errors during validation, allowing the form to submit successfully as long as the required field (name) was filled out correctly. Instead, I encountered a type error related to the resolver, indicating a mismatch in the expected types for the form data.
EDIT:
I'm also encountering an error related to the control when using the following components:
<InputController
name="name"
control={control}
error={errors.name?.message as string}
label="Name"
/>
<InputController
name="surname"
control={control}
error={errors.surname?.message as string}
label="Surname"
/>
<InputNumberController
name="age"
control={control}
error={errors.age?.message as string}
label="Age"
/>
The error message I receive is:
TS2322: Type
Control<{
name: string;
surname: string | undefined;
age: number | undefined;
}, unknown, {
surname?: string | undefined;
age?: number | undefined;
name: string;
}>
is not assignable to type
Control<{
surname?: string | undefined;
age?: number | undefined;
name: string;
}>
The types of _options.resolver are incompatible between these types.
Type 'Resolver<{ name: string; surname: string | undefined; age: number | undefined; }, unknown, { surname?: string | undefined; age?: number | undefined; name: string; }> | undefined' is not assignable to type 'Resolver<{ surname?: string | undefined; age?: number | undefined; name: string; }, any, { surname?: string | undefined; age?: number | undefined; name: string; }> | undefined'.
Type 'Resolver<{ name: string; surname: string | undefined; age: number | undefined; }, unknown, { surname?: string | undefined; age?: number | undefined; name: string; }>' is not assignable to type 'Resolver<{ surname?: string | undefined; age?: number | undefined; name: string; }, any, { surname?: string | undefined; age?: number | undefined; name: string; }>'.
Types of parameters options and options are incompatible.
Type 'ResolverOptions<{ surname?: string | undefined; age?: number | undefined; name: string; }>' is not assignable to type 'ResolverOptions<{ name: string; surname: string | undefined; age: number | undefined; }>'.
Type '{ surname?: string | undefined; age?: number | undefined; name: string; }' is not assignable to type '{ name: string; surname: string | undefined; age: number | undefined; }'.
Property surname is optional in type
{
surname?: string | undefined;
age?: number | undefined;
name: string;
}
but required in type
{
name: string;
surname: string | undefined;
age: number | undefined;
}
This error with control exists even before removing <YupFormData> from the useForm hook. While removing it resolves the resolver error, the control type mismatch persists. Any guidance on how to resolve this would be greatly appreciated!
EDIT: Here is my implementation of the InputController:
type InputControllerProps<T extends FieldValues> = {
name: Path<T>;
control: Control<T>;
rules?: Omit<RegisterOptions<T, Path<T>>, 'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'>;
error?: string;
label: string;
};
function InputController<T extends FieldValues>({
name, control, rules, error, label,
}: InputControllerProps<T>) {
return (
<Controller
name={name}
control={control}
rules={rules}
render={({ field }) => (
<input
{...field}
aria-label={label}
id={name}
style={{ borderColor: error ? 'red' : 'default' }} // Example of error handling
placeholder={label}
/>
)}
/>
);
}