datnm.qti
datnm.qti

Reputation: 11

React Hook Form and Zod: "invalid_type_error" Message Displayed Instead of "required_error"

I'm currently working with react-hook-form and zod for form validation in my React project. I have a specific field, let's call it age, with its input type set to the default (string). In the Zod schema, I explicitly define this field as a number using z.number().

Here's a simplified version of my code:

const Schema = z.object({
  age: z.number({
    required_error: "Required",
    invalid_type_error: "Invalid type",
  }),
});

type SchemaType = z.infer<typeof Schema>;

const form = useForm<SchemaType>({
  resolver: zodResolver(Schema),
});

The expected behavior is that when submitting the form without inputting anything in the age field, it should display the "Required" message. However, the actual behavior is that it shows the "Invalid type" message.

I'm using z.infer<typeof Schema> to ensure that the type of the age field is correctly inferred as number. Is there a way to resolve this issue and ensure that, when submitting without inputting anything, the "Required" message is displayed instead of the "Invalid type" message?

Then, I would like parse below object without error,

Schema.parse({
  age: 20
})

Thank you for your assistance!

Attempted Solution: I defined a Zod schema with the age field set to z.number() in order to enforce that it should be a number. I used z.infer<> to ensure the correct type. My form configuration uses react-hook-form with the Zod resolver.

Expected Outcome: I expected that when submitting the form without inputting anything into the age field, the validation should trigger the "Required" message as specified in the Zod schema.

Actual Result: However, the issue I encountered is that upon submission without input, the form displays the "Invalid type" message instead of the expected "Required" message. I'm seeking guidance on resolving this discrepancy.

Upvotes: 1

Views: 5249

Answers (2)

moshyfawn
moshyfawn

Reputation: 705

The input value returned by HTML is a string. To convert it into a number, you can use Zod's .coerce() operator. Take a look at this codesandbox example.

If you define your field value type as number but pass a string as the default field value, a type error will occur. To handle this, you can make the value type nullable and use null as the default number field value.

Another option is to use the setValueAs React Hook Form register method option to handle the field value conversion.

Upvotes: 2

WarlockJa
WarlockJa

Reputation: 11

The problem is that empty input field will submit NaN on form submit, which will be interpreted by Zod as type mismatch. I guess as a workaround you could make your Schema look like this

const Schema = z.object({
  age: z.number({
    invalid_type_error: "Age required",
  }),
});

which will provide more sensible error message. Otherwise you could raise an issue with the developers of "react-hook-form".

Upvotes: 1

Related Questions