react-hook-form useController可复用字段组件的类型约束优化
解决react-hook-form useController构建ControlledFieldText的类型问题
问题1:限制defaultValue仅为string类型
通过自定义组件Props的类型约束,直接将defaultValue限定为string | undefined,从外部传入阶段就阻止非string类型值。同时在useController内部通过类型断言适配react-hook-form的类型要求,且确保表单对应字段的类型必须为string(否则编译报错)。
问题2:允许""作为默认值
将defaultValue类型设为string | undefined后,空字符串""属于合法的string类型,可直接传入。组件内部再通过field.value ?? ''确保渲染时始终拿到字符串值,避免undefined。
完整组件代码示例
import { useController, Control, Path, FieldValues, PathValue } from 'react-hook-form'; import { FieldText } from './FieldText'; // 替换为你的FieldText组件路径 type ControlledFieldTextProps<T extends FieldValues> = { control: Control<T>; name: Path<T>; defaultValue?: string; label?: string; placeholder?: string; // 可添加其他需要的props }; export function ControlledFieldText<T extends FieldValues>({ control, name, defaultValue, ...restProps }: ControlledFieldTextProps<T>) { const { field } = useController({ control, name, // 类型断言适配react-hook-form的类型要求,若表单字段非string类型会编译报错 defaultValue: defaultValue as PathValue<T, Path<T>>, }); return ( <FieldText value={field.value ?? ''} onChange={(e) => field.onChange(e.target.value)} onBlur={field.onBlur} {...restProps} /> ); }
更严格的类型约束(可选)
如果需要强制表单对应字段的类型必须为string,可以给泛型T添加约束,这样使用组件时若表单字段类型不符会直接报错:
// 修改Props的泛型约束 type ControlledFieldTextProps<T extends FieldValues & Record<Path<T>, string>> = { control: Control<T>; name: Path<T>; defaultValue?: string; label?: string; placeholder?: string; };
内容的提问来源于stack exchange,提问作者markoffden
相关产品推荐
相关产品推荐

