React Hook Form自定义输入组件Props类型定义问题
解决React Hook Form通用FormInput组件的类型定义问题
你遇到的核心问题是泛型未正确约束到React Hook Form的FieldValues类型,以及未正确对应rules的类型。以下是完整的修正方案:
完整的类型定义与组件代码
首先确保从react-hook-form导入所需的类型:
import { Controller, Control, Path, RegisterOptions, FieldValues } from 'react-hook-form'; // 假设你的Input来自react-native,导入对应类型 import { Input, Text, StyleProp, TextStyle } from 'react-native';
然后定义带正确泛型约束的Props和组件:
type FormInputProps<T extends FieldValues> = { control: Control<T>; name: Path<T>; rules?: RegisterOptions<T, Path<T>>; shouldUnregister?: boolean; style?: StyleProp<TextStyle>; secureTextEntry?: boolean; placeholder?: string; }; const FormInput = <T extends FieldValues>({ name, control, rules, shouldUnregister, style, secureTextEntry, placeholder, }: FormInputProps<T>) => { return ( <Controller name={name} control={control} rules={rules} shouldUnregister={shouldUnregister} render={({ field: { onChange, onBlur, value }, fieldState: { error }, }) => ( <> <Input onBlur={onBlur} onChangeText={onChange} value={value} style={style} secureTextEntry={secureTextEntry} placeholder={placeholder} /> {error && <Text>{error.message || "Error"}</Text>} </> )} /> ); }; export default FormInput;
关键修正点说明
泛型约束:给泛型
T加上extends FieldValues,这是React Hook Form所有表单相关类型的基础约束,直接解决你之前遇到的Type 'T' does not satisfy the constraint 'FieldValues'错误。类型对应:
control使用Control<T>,无需额外参数,默认适配表单类型name使用Path<T>,确保它是表单对象T中存在的合法路径,同时自动触发字段名的补全提示rules使用RegisterOptions<T, Path<T>>,这是官方提供的验证规则类型,会根据当前字段的类型自动适配可用规则(比如字符串字段提示minLength,数字字段提示min等)
简化调用:当你在
useForm中指定表单类型后,组件会自动推断T,无需手动传入泛型参数:
import { useForm } from 'react-hook-form'; // 定义你的表单数据类型 type Program = { name: string; age?: number; email: string; }; const MyForm = () => { const { control } = useForm<Program>(); return ( <FormInput control={control} name="name" {/* 此处会自动补全Program的所有字段 */} rules={{ required: '姓名不能为空' }} placeholder="请输入姓名" /> ); };
之前尝试失败的原因
你之前的泛型未添加extends FieldValues约束,而React Hook Form的Control、Path等核心类型强制要求泛型参数必须是FieldValues的子类型,因此触发了类型错误。另外rules未使用官方提供的RegisterOptions类型,导致无法关联字段类型与验证规则。
内容的提问来源于stack exchange,提问作者Romain Hoffmann
相关产品推荐
相关产品推荐

