如何为自定义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
相关产品推荐
相关产品推荐

