react-hook-form中如何限制TFieldName仅对应string类型字段
问题原因
当前泛型定义仅约束TFieldName是TFieldValues的合法字段路径,未限制该路径对应的值类型,TypeScript无法推导目标字段的值一定为string,因此不允许将string类型的label赋值给要求匹配字段值类型的defaultValue属性,最终抛出类型不匹配错误。
解决方案
直接使用react-hook-form内置的FieldPathByValue工具类型,约束泛型TFieldName只能是值类型为string的表单字段路径,从类型层面保证传入的name对应的字段值一定为string,即可彻底消除报错。
修正后的完整组件代码:
import { FieldValues, Control, FieldPathByValue, useController } from 'react-hook-form'; // 保留你项目中原有useFieldContext的导入即可 interface FormFieldInputLabelProps< TFieldValues extends FieldValues = FieldValues, // 约束泛型仅接受值为string类型的字段路径 TFieldName extends FieldPathByValue<TFieldValues, string> = FieldPathByValue<TFieldValues, string> > { control: Control<TFieldValues>; name: TFieldName; } export function FormFieldInputLabel< TFieldValues extends FieldValues = FieldValues, TFieldName extends FieldPathByValue<TFieldValues, string> = FieldPathByValue<TFieldValues, string> >({ name, control }: FormFieldInputLabelProps<TFieldValues, TFieldName>) { const { label } = useFieldContext(); const { field } = useController({ control, name, // 此处label为string类型,完全匹配defaultValue的类型要求,无TS报错 defaultValue: label }); return <input type="hidden" {...field} />; };
兼容处理
如果你使用的react-hook-form版本较低,没有内置FieldPathByValue类型,可以自行实现仅支持一级字段的简易版类型工具:
// 筛选T对象中值类型匹配TValue的一级字段名 type FieldPathByValue<T, TValue> = { [K in keyof T]: T[K] extends TValue ? K : never }[keyof T];
加上该类型约束后,若尝试给组件的name属性传入值类型非string的字段路径,TypeScript会直接在组件调用位置抛出类型错误,提前规避运行时可能出现的类型不匹配问题。
内容的提问来源于stack exchange,提问作者Svish
相关产品推荐
相关产品推荐

