如何将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
相关产品推荐
相关产品推荐

