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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 09:02:25