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

TypeScript环境下React Hook Form的useController如何扩展额外属性

优化方案

核心思路是直接复用 react-hook-form 内置的 UseControllerProps 类型,通过 TypeScript 交叉类型扩展自定义属性,无需手动拷贝原生类型定义:

import { useController, UseControllerProps, FieldValues } from 'react-hook-form';

export type FormValues = {
  title: string;
  amount: number;
  url: string;
  price: number;
};

// 直接扩展原生UseControllerProps,新增自定义属性
type CustomInputProps<T extends FieldValues = FormValues> = UseControllerProps<T> & {
  type?: 'text' | 'number' | 'date' | 'url';
  label?: string;
}

const CustomInputHooked = <T extends FieldValues = FormValues>(props: CustomInputProps<T>) => {
  const { field, fieldState } = useController(props);
  return (
    <div>
      {props.label && <label htmlFor={field.name}>{props.label}</label>}
      {/* 优先使用传入的type,默认fallback为text */}
      <input {...field} type={props.type ?? 'text'} id={field.name} />
      <p>{fieldState.isTouched && 'Touched'}</p>
      <p>{fieldState.isDirty && 'Dirty'}</p>
      <p>{fieldState.invalid ? 'invalid' : 'valid'}</p>
    </div>
  );
};

使用时直接传入自定义属性即可,类型校验完全正常:

<CustomInputHooked 
  control={control} 
  name="title" 
  rules={{ required: true }}
  label="商品标题"
  type="text"
/>
<CustomInputHooked
  control={control}
  name="amount"
  rules={{ required: true, maxLength: 5, pattern: /[0-9]/g }}
  label="商品数量"
  type="number"
/>

方案优势

  • 完全复用官方维护的类型定义,无需手动同步react-hook-form版本迭代带来的类型变动
  • 保留泛型支持,组件可以复用到任意结构的表单场景,不需要绑定死固定的FormValues类型
  • 无冗余代码,新增自定义属性只需在交叉类型中加字段即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:54:03