T
TanStack2mo ago
ambitious-aqua

TanStack Form + Zod: Type error with enum default values in onChange validator

Having a TypeScript issue with TanStack Form + Zod schema validation. Getting a type error when using my schema in the onChange validator. Schema:
export const beverageSchema = z.enum(['coffee', 'tea', 'water']).default('water')

export const peopleSchema = z.object({
fullName: z.string().min(1, 'Full name is required'),
email: z.string().optional(),
phone: z.string().min(1, 'Phone is required'),
address: addressSchema,
beverage: beverageSchema, // Has default but not optional
})

export const peopleFormOpts = formOptions({
defaultValues: {} as PeopleFormData, // Empty defaults
})
export const beverageSchema = z.enum(['coffee', 'tea', 'water']).default('water')

export const peopleSchema = z.object({
fullName: z.string().min(1, 'Full name is required'),
email: z.string().optional(),
phone: z.string().min(1, 'Phone is required'),
address: addressSchema,
beverage: beverageSchema, // Has default but not optional
})

export const peopleFormOpts = formOptions({
defaultValues: {} as PeopleFormData, // Empty defaults
})
Form usage:
const form = useAppForm({
...peopleFormOpts,
validators: {
onChange: peopleSchema, // ❌ Type error here
},
onSubmit: ({ value }) => {
alert(JSON.stringify(value, null, 2))
},
})
const form = useAppForm({
...peopleFormOpts,
validators: {
onChange: peopleSchema, // ❌ Type error here
},
onSubmit: ({ value }) => {
alert(JSON.stringify(value, null, 2))
},
})
Type error:
The types of 'input.beverage' are incompatible between these types.
Type '"coffee" | "tea" | "water" | undefined' is not assignable to type '"coffee" | "tea" | "water"'.
Type 'undefined' is not assignable to type '"coffee" | "tea" | "water"'.
The types of 'input.beverage' are incompatible between these types.
Type '"coffee" | "tea" | "water" | undefined' is not assignable to type '"coffee" | "tea" | "water"'.
Type 'undefined' is not assignable to type '"coffee" | "tea" | "water"'.
What I need: 1. Use Zod schema directly in onChange validator (no manual parsing) - so I can have field level errors 2. Keep typed default values for child forms The beverage field has a default value but isn't optional - should TanStack Form handle this automatically? How can I resolve this type mismatch while maintaining the schema structure? Here is a reproduction repo: https://github.com/snigdha920/tanstack-zod/tree/main
GitHub
GitHub - snigdha920/tanstack-zod
Contribute to snigdha920/tanstack-zod development by creating an account on GitHub.
2 Replies
fascinating-indigo
fascinating-indigo2mo ago
It's likely because of a mismatch between the validator's expected type and the default values. There purpose of typing the validator schema is to avoid accidentally locking your form (by setting errors at fields that never exist). It's a bit too strict at the moment though, which you can confirm yourself by comparing * Your default values * z.input<typeof yourSchema> which is the input expected from zod. Note that it's not the same as infer which is the output. A user reached out and suggested type changes so it's more lenient while still avoiding the mentioned problem, you can read up on chatlog here: https://github.com/TanStack/form/issues/1583 based on the error, you probably have undefined set as the default value, while it actually expects an enum. It's a bit strange that zod doesn't widen the type if you have a default, since it's purposefully built for undefined right?
ambitious-aqua
ambitious-aquaOP2mo ago
Ah! Typing the defaultValues as z.input<typeof peopleSchema> instead of infer fixes the type mismatch. It makes sense, since the defaultValues are inputs to the form, instead of outputs. I didn't know about the difference between infer and input, thank you so much!

Did you find this page helpful?