React TypeScript中react-hook-form TS2345类型不匹配错误求助
解决React TypeScript中react-hook-form的TS2345类型错误
问题根源
从props中提取的name被TypeScript推断为string类型,但register函数要求的是SignUpFields接口的具体键名("firstName" | "lastName" | "email" | "password" | "location"),类型不匹配导致报错。
修复步骤及代码
1. 给组件添加泛型约束,明确字段类型
将InputElement改为泛型组件,让它适配SignUpFields的任意键,同时精准约束name、rules和error的类型:
import { InputHTMLAttributes } from "react"; import { UseFormRegister, FieldError, RegisterOptions } from "react-hook-form"; interface SignUpFields { firstName: string; lastName: string; email: string; password: string; location: string; } // 用泛型K约束name必须是SignUpFields的键 interface InputElementProps<K extends keyof SignUpFields> extends Omit<InputHTMLAttributes<HTMLInputElement>, "name"> { label?: string; labelClasses?: string; register: UseFormRegister<SignUpFields>; rules: RegisterOptions<SignUpFields, K>; error?: FieldError; name: K; // 明确name是SignUpFields的键类型 } export function InputElement<K extends keyof SignUpFields>({ label, labelClasses, register, rules, error, name, // 直接解构name,不用从props里间接取 ...props }: InputElementProps<K>) { return ( <div className="mt-6"> {label && ( <label htmlFor={props.id} className={`block text-primary text-sm font-medium font-montserrat leading-6 ${labelClasses}`} > {label} </label> )} <input {...props} {...register(name, rules)} className="mt-2 mb-1 bg-transparent active:bg-transparen focus:bg-transparent block w-full rounded-xl border-2 border-primary px-4 py-2 font-montserrat text-lg text-white placeholder:text-white sm:text-sm sm:leading-6" /> {error && ( <p className="text-white text-xs font-montserrat mt-1 italic"> {error.message} </p> )} </div> ); }
2. 父组件使用无需修改
原父组件的调用方式保持不变,TypeScript会自动推断K的类型:
<InputElement id="First Name" name="firstName" type="text" label="First Name" register={register} rules={{ required: "First name is required." }} error={errors.firstName} />
关键修改点说明
- 用
Omit<InputHTMLAttributes<HTMLInputElement>, "name">覆盖原生name的string类型,替换为K extends keyof SignUpFields,确保name只能是SignUpFields的有效键。 - 直接解构
name参数,避免从props间接取值导致的类型丢失。 - 将
rules的类型从FieldValues改为RegisterOptions<SignUpFields, K>,让校验规则和对应字段的类型严格匹配。
内容的提问来源于stack exchange,提问作者user3330820
相关产品推荐
相关产品推荐

