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

react-hook-form useController可复用字段组件的类型约束优化

解决react-hook-form useController构建ControlledFieldText的类型问题

问题1:限制defaultValue仅为string类型

通过自定义组件Props的类型约束,直接将defaultValue限定为string | undefined,从外部传入阶段就阻止非string类型值。同时在useController内部通过类型断言适配react-hook-form的类型要求,且确保表单对应字段的类型必须为string(否则编译报错)。

问题2:允许""作为默认值

将defaultValue类型设为string | undefined后,空字符串""属于合法的string类型,可直接传入。组件内部再通过field.value ?? ''确保渲染时始终拿到字符串值,避免undefined。

完整组件代码示例

import { useController, Control, Path, FieldValues, PathValue } from 'react-hook-form';
import { FieldText } from './FieldText'; // 替换为你的FieldText组件路径

type ControlledFieldTextProps<T extends FieldValues> = {
  control: Control<T>;
  name: Path<T>;
  defaultValue?: string;
  label?: string;
  placeholder?: string;
  // 可添加其他需要的props
};

export function ControlledFieldText<T extends FieldValues>({
  control,
  name,
  defaultValue,
  ...restProps
}: ControlledFieldTextProps<T>) {
  const { field } = useController({
    control,
    name,
    // 类型断言适配react-hook-form的类型要求,若表单字段非string类型会编译报错
    defaultValue: defaultValue as PathValue<T, Path<T>>,
  });

  return (
    <FieldText
      value={field.value ?? ''}
      onChange={(e) => field.onChange(e.target.value)}
      onBlur={field.onBlur}
      {...restProps}
    />
  );
}

更严格的类型约束(可选)

如果需要强制表单对应字段的类型必须为string,可以给泛型T添加约束,这样使用组件时若表单字段类型不符会直接报错:

// 修改Props的泛型约束
type ControlledFieldTextProps<T extends FieldValues & Record<Path<T>, string>> = {
  control: Control<T>;
  name: Path<T>;
  defaultValue?: string;
  label?: string;
  placeholder?: string;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:43:32