TypeScript如何创建可处理不同参数类型的泛型函数
解决TypeScript泛型函数中参数类型关联问题
问题场景
你尝试创建可接收不同参数的泛型函数,但TypeScript无法识别type与value的对应类型,报错:
Argument of type 'string | number' is not assignable to parameter of type 'never'. Type 'string' is not assignable to type 'never'. (2345)
原示例代码:
const typeToFn = { text: (value: string) => value, integer: (value: number) => value, }; type Type = keyof typeof typeToFn; type Value<TType extends Type> = Parameters<(typeof typeToFn)[TType]>[0] function callFn<TType extends Type>(type: TType, value: Value<TType>) { const fn = typeToFn[type] return fn(value) }
原因分析
原代码中,typeToFn[type]的类型被推断为联合类型((value: string) => string) | ((value: number) => number),而泛型TType对应的value类型是Value<TType>。TypeScript无法在泛型上下文里确定fn的具体类型与value类型严格匹配,因此会将参数类型的交集计算为string & number(即never),触发类型错误。
解决方案
方案1:使用联合元组约束参数(推荐)
通过生成包含所有合法参数组合的联合元组类型,让TypeScript直接识别每个type对应的value类型:
const typeToFn = { text: (value: string) => value, integer: (value: number) => value, // 可扩展更多类型 boolean: (value: boolean) => value, }; type TypeToFn = typeof typeToFn; // 生成[type, value]的联合元组类型,覆盖所有合法参数组合 type CallFnArgs = { [K in keyof TypeToFn]: [type: K, value: Parameters<TypeToFn[K]>[0]] }[keyof TypeToFn]; function callFn(...args: CallFnArgs) { const [type, value] = args; const fn = typeToFn[type]; return fn(value); } // 测试用例 callFn('text', 'hello'); // 类型正确 callFn('integer', 123); // 类型正确 callFn('boolean', true); // 类型正确 callFn('text', 123); // 类型错误(符合预期)
这种方式无需额外断言,TypeScript能自动推断参数的对应关系,且扩展新类型时只需修改typeToFn对象即可,维护性更好。
方案2:使用类型断言(快速修复)
如果不想重构函数参数结构,可以通过类型断言明确告知TypeScript当前fn的类型:
const typeToFn = { text: (value: string) => value, integer: (value: number) => value, }; type Type = keyof typeof typeToFn; type Value<TType extends Type> = Parameters<(typeof typeToFn)[TType]>[0]; function callFn<TType extends Type>(type: TType, value: Value<TType>) { // 断言fn为与TType匹配的函数类型 const fn = typeToFn[type] as (value: Value<TType>) => ReturnType<(typeof typeToFn)[TType]>; return fn(value); }
注意:这种方式需要手动维护断言类型,若后续typeToFn新增或修改类型,需同步调整断言,适合简单场景临时修复。
内容的提问来源于stack exchange,提问作者Heloi Neto
相关产品推荐
相关产品推荐

