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

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;

关键修正点说明

  1. 泛型约束:给泛型T加上extends FieldValues,这是React Hook Form所有表单相关类型的基础约束,直接解决你之前遇到的Type 'T' does not satisfy the constraint 'FieldValues'错误。

  2. 类型对应:

    • control使用Control<T>,无需额外参数,默认适配表单类型
    • name使用Path<T>,确保它是表单对象T中存在的合法路径,同时自动触发字段名的补全提示
    • rules使用RegisterOptions<T, Path<T>>,这是官方提供的验证规则类型,会根据当前字段的类型自动适配可用规则(比如字符串字段提示minLength,数字字段提示min等)
  3. 简化调用:当你在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:25:17