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

如何为自定义Hook推导基于传入参数的类型?

解决方案

首先定义表单字段的完整类型,明确公共字段与可选字段的类型约束:

// 表单字段的完整类型定义
type FormFields = {
  commonField: string; // 所有组件共用的公共字段
  optionalField1: string; // 默认可选字段,类型为字符串
  optionalField2: number; // 另一个可选字段,类型为数字
};

接下来给自定义Hook添加泛型约束,让可选字段名的类型与对应字段值类型绑定,同时设置默认值确保未传参时的类型推导:

import { useForm, UseFormReturn } from 'react-hook-form';

// 限制可选字段名只能是指定的两个字段
type OptionalFieldName = keyof Pick<FormFields, 'optionalField1' | 'optionalField2'>;

function useCustomHook<
  T extends OptionalFieldName = 'optionalField1'
>(
  methods: UseFormReturn<FormFields>,
  optionalFieldName: T = 'optionalField1' as T
) {
  // 公共字段类型自动正确推导
  const commonFieldValue = methods.watch('commonField');
  
  // 通过泛型T获取对应字段的精准类型,替代any
  const fieldValue = methods.watch(optionalFieldName) as FormFields[T];

  return {
    commonFieldValue,
    fieldValue
  };
}

调用示例

  • 未传入可选字段名时,默认使用optionalField1,fieldValue自动推导为string类型:
const methods = useForm<FormFields>();
const { fieldValue } = useCustomHook(methods);
// fieldValue 类型:string
  • 传入optionalField2时,fieldValue自动推导为number类型:
const methods = useForm<FormFields>();
const { fieldValue } = useCustomHook(methods, 'optionalField2');
// fieldValue 类型:number

核心逻辑说明

  • 用Pick<FormFields, ...>约束泛型参数的可选范围,避免传入无效字段名;
  • 泛型默认值= 'optionalField1'确保未传参时自动匹配默认字段的类型;
  • 通过FormFields[T]直接映射字段名到对应类型,彻底解决watch返回值为any的问题。

内容的提问来源于stack exchange,提问作者Ismail Gül

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 16:15:51