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

React Native中使用React Hook Form的TypeScript类型错误求助

问题解决:React Hook Form + TypeScript 受控组件name属性类型错误

问题背景

在React Native项目里用React Hook Form实现表单控制时,给ControlledTextInput传name属性(比如"username")时出现TypeScript类型错误,提示"username"不能赋值给never类型。

代码示例

Home表单组件

import { useForm } from 'react-hook-form';
import ControlledTextInput from './ControlledTextInput';
import { View } from 'react-native';

type FormValues = {
  username: string;
  password: string;
};

export default function Home() {
  const { control } = useForm<FormValues>({
    defaultValues: {
      username: '',
      password: '',
    },
  });

  return (
    <View>
      <ControlledTextInput
        control={control}
        name="username" // ❌ 此处出现类型错误
        placeholder="用户名"
      />
      <ControlledTextInput
        control={control}
        name="password" // ❌ 此处出现类型错误
        placeholder="密码"
        secureTextEntry
      />
    </View>
  );
}

ControlledTextInput受控输入组件

import { Controller, Control } from 'react-hook-form';
import Input from './Input';

type ControlledTextInputProps = {
  control: Control;
  name: string;
  placeholder: string;
  secureTextEntry?: boolean;
};

export default function ControlledTextInput({
  control,
  name,
  placeholder,
  secureTextEntry,
}: ControlledTextInputProps) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field: { onChange, value } }) => (
        <Input
          onChangeText={onChange}
          value={value}
          placeholder={placeholder}
          secureTextEntry={secureTextEntry}
        />
      )}
    />
  );
}

Input基础输入组件

import { TextInput, TextInputProps } from 'react-native';

type InputProps = TextInputProps & {
  // 自定义属性(如有)
};

export default function Input(props: InputProps) {
  return <TextInput {...props} />;
}

错误原因

ControlledTextInput的类型定义太笼统:control用了无泛型的Control类型,name只是普通string,完全没和表单的FormValues类型关联。React Hook Form无法推断出name应该是FormValues里的合法键,直接把name的类型判定为never,导致传入合法字段名也报错。

修复方案

给ControlledTextInput添加泛型,让它和表单的FormValues类型挂钩,TypeScript就能准确识别合法的name字段了。

修改后的ControlledTextInput代码:

import { Controller, Control, FieldPath } from 'react-hook-form';
import Input from './Input';

// 新增泛型T,关联表单值类型
type ControlledTextInputProps<T> = {
  control: Control<T>;
  // 用FieldPath<T>约束name必须是T的合法键
  name: FieldPath<T>;
  placeholder: string;
  secureTextEntry?: boolean;
};

// 组件改为泛型组件
export default function ControlledTextInput<T>({
  control,
  name,
  placeholder,
  secureTextEntry,
}: ControlledTextInputProps<T>) {
  return (
    <Controller
      control={control}
      name={name}
      render={({ field: { onChange, value } }) => (
        <Input
          onChangeText={onChange}
          value={value}
          placeholder={placeholder}
          secureTextEntry={secureTextEntry}
        />
      )}
    />
  );
}

在Home组件中使用时,显式指定泛型(TypeScript也可自动推断,显式声明更清晰):

<ControlledTextInput<FormValues>
  control={control}
  name="username" // ✅ 类型检查通过
  placeholder="用户名"
/>

<ControlledTextInput<FormValues>
  control={control}
  name="password" // ✅ 类型检查通过
  placeholder="密码"
  secureTextEntry
/>

额外说明

  • FieldPath<T>是React Hook Form提供的工具类型,专门用来约束表单字段名,能避免拼写错误或传入不存在的字段。
  • 改成泛型组件后,ControlledTextInput可以复用在任何结构的表单中,只需传入对应的表单值类型即可。

内容的提问来源于stack exchange,提问作者Ming

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:12:41