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

react-hook-form中Controller组件name属性参数化的类型错误问题

解决React Hook Form动态Controller的name类型错误问题

我开发了一个表单组件,能根据数组(如['firstName', 'lastName'])动态生成表单字段,但在给react-hook-form的Controller组件的name属性使用变量时出现类型错误,尝试转换为FieldPath等类型也没用。已经成功创建了动态defaultValues对象,但不知道怎么通过变量name关联每个Controller来消除报错。试过用...register也有同样的类型错误,而且因为用的不是原生输入组件,官方推荐用Controller。


要解决这个类型错误,核心是让TypeScript明确识别表单字段的合法类型,确保动态字段名属于表单结构的有效键。具体实现步骤如下:

  • 定义表单数据类型:声明表单数据的TS类型,为所有字段建立明确的类型约束。
  • 约束动态字段数组类型:将inputFields定义为表单类型键的数组,保证每个元素都是合法的字段名。
  • 指定useForm泛型:初始化useForm时传入表单类型作为泛型,让Hook自动推断出正确的FieldPath类型。

修改后的完整代码:

import { Controller, useForm } from "react-hook-form";

// 1. 定义表单数据的类型结构
type FormData = {
  firstName: string;
  lastName: string;
};

function App() {
  // 2. 约束inputFields为FormData的合法键数组
  const inputFields: Array<keyof FormData> = ["firstName", "lastName"];

  // 3. 生成符合FormData类型的defaultValues
  const formDefaultValues: FormData = inputFields.reduce((acc, field) => {
    acc[field] = "";
    return acc;
  }, {} as FormData);

  // 4. 给useForm指定泛型,明确表单数据结构
  const {
    control,
    handleSubmit,
    formState: { errors, isValid },
  } = useForm<FormData>({
    defaultValues: formDefaultValues,
  });

  // 提交函数的参数类型也会自动匹配FormData
  const onSubmit = (data: FormData) => console.log(data);

  return (
    <>
      {inputFields.map((x) => (
        <Controller
          key={x}
          name={x} // TypeScript自动识别x为合法的FieldPath
          control={control}
          render={({ field }) => (
            <div>
              <input {...field} /> {/* 直接展开field,自动绑定value、onChange等属性 */}
            </div>
          )}
        />
      ))}
      <button onClick={handleSubmit(onSubmit)}>Test values</button>
    </>
  );
}

export default App;

关键说明

  1. 类型约束的作用:FormData类型不仅能校验表单数据结构,还能让TypeScript自动校验inputFields中的字段名是否合法,避免拼写错误。
  2. 动态字段的类型匹配:Array<keyof FormData>确保inputFields中的每个元素都是FormData的有效键,因此x作为Controller的name时,会被自动识别为FieldPath<FormData>类型,消除类型错误。
  3. 简洁的属性绑定:直接展开field到输入组件上,能一次性绑定value、onChange、onBlur等必要属性,比单独写onChange={field.onChange}更高效。

内容的提问来源于stack exchange,提问作者Vlad Mihai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:54:55