React Hook Form泛型扩展类型中register函数类型错误问题
TypeScript + React Hook Form 泛型组件类型错误解决
问题背景
定义了两个类型:
type Basic = { a: string }; type Extended = Basic & { b: string };
希望构建一个支持所有继承Basic类型的通用视图组件,编写代码如下:
import React from 'react'; import { UseFormRegister, useForm } from 'react-hook-form'; function GenericView<T extends Basic>({ register, }: { register: UseFormRegister<T>; }) { return <input {...register('a')} />; } function MainView({ register }: { register: UseFormRegister<Extended> }) { return ( <> <input {...register('b')} /> <GenericView register={register} /> </> ); } export function Main() { const { register } = useForm<Extended>(); return <MainView register={register} />; }
运行代码时,GenericView中出现TypeScript错误:
Argument of type '"a"' is not assignable to parameter of type 'Path
'.
解决方案
错误源于React Hook Form的Path<T>类型无法通过T extends Basic的约束,推断出T必然包含a字段,以下是几种可行的解决方式:
方式一:强化泛型约束
修改GenericView的泛型约束,通过交叉类型让Path明确识别a字段:
function GenericView<T extends Basic>({ register, }: { register: UseFormRegister<T & Basic>; }) { return <input {...register('a')} />; }
方式二:类型断言指定路径
通过类型断言直接声明'a'是合法的路径类型:
import { Path, UseFormRegister, useForm } from 'react-hook-form'; function GenericView<T extends Basic>({ register, }: { register: UseFormRegister<T>; }) { return <input {...register('a' as Path<T & Basic>)} />; }
方式三:自定义类型辅助工具
创建类型工具确保T必须包含目标字段,增强类型严谨性:
type EnsureHasKey<T, K extends string> = T extends Record<K, any> ? T : never; function GenericView<T extends EnsureHasKey<Basic, 'a'>>({ register, }: { register: UseFormRegister<T>; }) { return <input {...register('a')} />; }
内容的提问来源于stack exchange,提问作者Shula
相关产品推荐
相关产品推荐

