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

如何正确设置react-hook-form中setValue的TypeScript类型并传参给子组件

react-hook-form 传递 setValue 到子组件的类型不匹配解决方案

报错原因

当父组件通过 useForm<Inputs> 显式指定表单的字段泛型为具体结构 Inputs 时,返回的 setValue 类型会被绑定为 UseFormSetValue<Inputs>。如果子组件在定义Props时,给 setValue、register 预留的类型是适配通用结构的 UseFormSetValue<Record<string, any>>,就会因为泛型结构不匹配触发TS类型校验报错:

Type 'UseFormSetValue<Inputs>' is not assignable to type 'UseFormSetValue<Record<string, any>>'

本质是TS的泛型匹配规则决定了:绑定了精确字段结构的函数类型,无法直接赋值给适配更宽松通用结构的同泛型类型,因为两者的参数约束范围不匹配。

正确修复方式

  • 第一步:抽取统一的表单字段类型,作为父子组件共享的类型基准
    不要在父子组件各自定义重复的表单字段类型,也不要在子组件Props里硬写Record<string, any>作为类型占位,统一抽离可复用的类型定义:
    // 公共表单字段类型,父子组件复用同一引用
    type Inputs = {
      field1: string
      field2: number
    }
    
  • 第二步:子组件Props与父组件传入的类型对齐
    从react-hook-form中导入对应的工具类型,和父组件使用的Inputs泛型保持一致,不要使用通用的Record<string, any>占位:
    import type { UseFormSetValue, UseFormRegister } from 'react-hook-form'
    
    // 定义子组件Props类型
    type Field2Props = {
      setValue: UseFormSetValue<Inputs>
      register: UseFormRegister<Inputs>
    }
    
    const Field2 = ({ setValue, register }: Field2Props) => {
      // 子组件内部可正常调用setValue、register,且保留完整的TS类型提示
      return (
        <div>
          <input {...register('field1')} />
          <button onClick={() => setValue('field2', 100)}>
            触发字段值更新
          </button>
        </div>
      )
    }
    
    父组件传值时不需要额外处理,直接将解构出的setValue、register传入子组件即可,类型校验会自动通过。
  • 第三步:如果子组件需要跨不同表单结构复用,可定义为泛型组件
    如果子组件不希望绑定固定的Inputs类型,可以将组件本身改为泛型结构,把表单类型从父组件透传下来,保留类型安全的同时提升复用性:
    import type { UseFormSetValue, UseFormRegister, FieldValues } from 'react-hook-form'
    
    // 泛型Props定义,约束表单字段结构继承react-hook-form的基础类型
    type GenericFieldProps<T extends FieldValues> = {
      setValue: UseFormSetValue<T>
      register: UseFormRegister<T>
    }
    
    // 定义为泛型组件
    const GenericField = <T extends FieldValues>({ setValue, register }: GenericFieldProps<T>) => {
      return (
        <div>
          <button onClick={() => setValue('commonField' as keyof T, '统一值')}>
            公共操作
          </button>
        </div>
      )
    }
    

注意:不要为了快速消除报错给传入的setValue添加as any的类型断言,这种写法会完全绕过TS的类型检查,后续出现字段名写错、值类型不匹配的问题时不会触发编译提示,容易引入线上隐患。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 04:45:04