React Hook Form onChange事件类型校验问题及解决方案咨询
const sampleSchema= z.object({ sampleData: z.array( z.object({ flag: z.boolean(), value: z.number() }) ), }); type FormInput = z.input<typeof sampleSchema>; const SampleComponent = () => { const { control } = useFormContext<FormInput>(); const { field } = useController({ control, name: 'sampleData' }); return ( <input onChange={(event) => { field.onChange([ ...field.value, ...[ { flag: true, // does not have value }, ], ]); }} /> ); };
这段代码里,Zod Schema明确要求sampleData数组的每个元素必须包含boolean类型的flag和number类型的value,但当前field.onChange()没有做严格类型校验,导致可以传入缺少value的非法对象。针对你提出的两个问题,解答如下:
问题解答
1. 是否可以为onChange传递显式类型?
完全可以,这也是最直接的解决方案。你可以利用已定义的FormInput类型约束传入onChange的值,让TypeScript在编译阶段就拦截不符合Schema的对象:
优化后的代码示例
onChange={(event) => { // 显式声明新元素的类型,缺省value会直接触发TypeScript报错 const newItem: FormInput['sampleData'][number] = { flag: true, value: 456, }; field.onChange([ ...field.value, newItem, ]); }}
如果不想单独声明变量,也可以直接给数组做类型断言,但显式声明变量类型的可读性更强,更推荐使用。
2. 如果无法实现,是否可以使用ESLint等工具检测使用扩展运算符合并不同类型数组的代码并标记为错误?
可以通过ESLint结合TypeScript规则实现:
- 启用
@typescript-eslint/restrict-plus-operands规则:该规则会检测扩展运算符合并不同类型数组的场景,直接抛出错误。 - 配合TypeScript的
strict模式:开启后会强化类型检查,避免any类型导致的校验失效。 - 启用
@typescript-eslint/no-explicit-any规则:禁止使用any类型,从根源上减少类型校验漏洞。
这些规则可以直接在ESLint配置文件中开启,示例如下:
module.exports = { rules: { '@typescript-eslint/restrict-plus-operands': 'error', '@typescript-eslint/no-explicit-any': 'error', }, };
内容的提问来源于stack exchange,提问作者Take
相关产品推荐
相关产品推荐

