You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:42:39