如何在TypeScript中使用泛型从字典调用带对应参数的函数
修复 TypeScript 扩展参数错误(ts2556)
你的代码报错的核心原因是把函数类型当成了参数传入,而不是函数对应的参数元组。
问题分析
你定义的 functionParams: TypeFnDict[T]["fn"] 实际上是获取了函数本身的类型(比如 (a: number, b: number) => string),但调用函数时需要的是该函数接受的参数元组(比如 [number, number])。TypeScript 无法对函数类型执行扩展操作,因此抛出「扩展参数必须具有元组类型」的错误。
正确实现方式
利用你已经定义好的 TypeFnDict 中的 params 字段(或者直接用 Parameters 工具类型),将 functionParams 类型指定为对应函数的参数元组即可:
type TypeFnDict = { nameOne: { params: Parameters<typeof functionOne>, fn: typeof functionOne }, nameTwo: { params: Parameters<typeof functionTwo>, fn: typeof functionTwo } }; const FunctionsDict = { nameOne: functionOne, nameTwo: functionTwo, }; function functionOne(a: number, b: number) { return `${a - b}`; }; function functionTwo(a: string, b: string, c: number) { return a + b + `${c}`; }; // 修正后的createStuff函数 const createStuff = function<T extends keyof TypeFnDict>( functionName: T, functionParams: TypeFnDict[T]["params"] // 使用预定义的参数元组类型 ) { return FunctionsDict[functionName](...functionParams); };
简化版本(无需TypeFnDict)
如果你不需要单独维护 TypeFnDict,可以直接基于 FunctionsDict 推导类型,代码更简洁:
const FunctionsDict = { nameOne: function(a: number, b: number) { return `${a - b}`; }, nameTwo: function(a: string, b: string, c: number) { return a + b + `${c}`; }, }; const createStuff = function<T extends keyof typeof FunctionsDict>( functionName: T, functionParams: Parameters<typeof FunctionsDict[T]> ): ReturnType<typeof FunctionsDict[T]> { return FunctionsDict[functionName](...functionParams); };
验证调用
现在你可以正确调用函数,TypeScript 会自动校验参数类型:
// 合法调用 createStuff('nameOne', [10, 5]); // 返回 "5" createStuff('nameTwo', ['Hello', 'World', 2024]); // 返回 "HelloWorld2024" // 非法调用会被TypeScript拦截 createStuff('nameOne', ['foo', 5]); // 参数类型不匹配,编译报错
内容的提问来源于stack exchange,提问作者Daniel Guedes
相关产品推荐
相关产品推荐

