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

如何将React Hook Form中Render Prop的any类型改为unknown?

解决react-hook-form中Controller的field.value类型为any的问题

核心原因

react-hook-form的Controller组件默认未指定泛型时,field.value的类型会被推导为any,这是因为库的默认泛型参数为any。要将其改为unknown,可以通过以下几种方式实现:

方法1:为Controller指定泛型类型

最规范的方式是为Controller明确表单值的泛型类型,若不确定具体字段类型,可直接用Record<string, unknown>作为泛型参数,这样field.value会自动变为unknown:

import { Controller } from 'react-hook-form';

// 定义表单值类型,用unknown覆盖默认的any
type FormValues = Record<string, unknown>;

const ControllerInput: React.FC<ControllerInputProps> = ({
  control,
  name,
  label
}: ControllerInputProps) => (
  <Controller<FormValues>
    control={control}
    name={name}
    render={({
      field: { onChange, onBlur, value }, // 此时value类型为unknown
      fieldState: { invalid, isTouched },
    }) => (
      <IonInput
        className={setFormControllerImportClass(invalid, isTouched)}
        label={label}
        name={name}
        value={value as string} // 若IonInput需要string类型,可在此断言
        onIonBlur={onBlur}
      />
    )}
  />
);

方法2:直接在解构时指定value类型

如果不想全局指定泛型,也可以在解构field时,直接为value指定unknown类型:

render={({
  field: { onChange, onBlur, value = undefined as unknown },
  fieldState: { invalid, isTouched },
}) => (
  <IonInput
    className={setFormControllerImportClass(invalid, isTouched)}
    label={label}
    name={name}
    value={value as string}
    onIonBlur={onBlur}
  />
)}

方法3:自定义Render Props类型

通过定义自定义接口来约束render prop的参数类型,强制value为unknown:

import { FieldState } from 'react-hook-form';

// 自定义render prop的类型
type CustomControllerRenderProps = {
  field: {
    onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
    onBlur: () => void;
    value: unknown;
  };
  fieldState: FieldState;
};

const ControllerInput: React.FC<ControllerInputProps> = ({
  control,
  name,
  label
}: ControllerInputProps) => (
  <Controller
    control={control}
    name={name}
    render={({ field, fieldState }: CustomControllerRenderProps) => (
      <IonInput
        className={setFormControllerImportClass(fieldState.invalid, fieldState.isTouched)}
        label={label}
        name={name}
        value={field.value as string}
        onIonBlur={field.onBlur}
      />
    )}
  />
);

注意事项

  • 不推荐直接修改第三方库的类型定义(如通过模块扩充),这会影响全局类型,且后续库版本更新可能导致冲突。
  • 如果能明确表单字段的具体类型(如{ username: string; age: number }),建议用具体类型代替Record<string, unknown>,这样类型检查会更严格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:23:33