如何为可选数字属性设置空字符串作为默认值?
问题与解决方案
问题背景
表单字段要求:可留空,若填写则必须是数字。结合react-hook-form与Zod时遇到两个矛盾点:
- 必须设置默认值,否则React会警告「受控组件不能转为非受控组件」;
- 设置空字符串
""作为optionalNumber的默认值时,TypeScript报错,提示类型不兼容。
原Zod Schema定义:
const mySchema = z.object({ optionalNumber: z.literal('') .or(z.coerce.number()) .transform(val => val === '' ? undefined : val) })
设置默认值时的TypeScript报错:
const form = useForm<z.infer<typeof mySchema>>({ resolver: zodResolver(mySchema), defaultValues: { optionalNumber: '' // TS2322: Type string is not assignable to type number } });
报错原因:z.infer<T>获取的是Zod解析后的输出类型,而defaultValues需要匹配Zod的输入类型,两者不匹配导致类型校验失败。
解决方案
利用Zod的z.input<T>类型推断,明确指定useForm的泛型为Schema的输入类型,即可解决类型冲突:
优化后的Zod Schema
const mySchema = z.object({ optionalNumber: z.string().optional().transform((val) => { if (val === '' || typeof val === 'undefined') { return undefined; } else { return parseInt(val, 10); } }).refine((val) => typeof val === 'undefined' || val >= 0, { message: "价格不能小于0" }) })
正确配置useForm
const form = useForm<z.input<typeof mySchema>>({ resolver: zodResolver(mySchema), defaultValues: { optionalNumber: '' } });
内容的提问来源于stack exchange,提问作者dschulten
相关产品推荐
相关产品推荐

