TypeScript函数与参数类型匹配:解决参数展开编译错误
解决TypeScript中函数与参数的类型匹配问题
核心问题分析
你遇到的编译错误本质是:当name为联合类型时,TypeScript无法将fns[name]和argsArr[name]的类型进行关联,它只能推断出两者各自的联合类型,但无法保证联合中的每一组函数和参数是一一匹配的,因此不允许直接展开参数。
解决方案:用映射类型绑定函数与参数的对应关系
我们可以先定义一个函数映射类型,让TypeScript明确每个函数名称对应的函数签名,再基于这个类型约束参数数组的结构,最后通过泛型收窄name的类型,让TypeScript追踪到具体的函数-参数匹配关系。
步骤1:定义统一的函数映射类型
// 明确每个函数名称对应的函数签名 type FuncMap = { f1: () => void; f2: (a: string) => void; f3: (a: string, b: string) => void; };
步骤2:基于映射类型定义函数和参数数组
这里确保argsArr的每个属性严格对应FuncMap中函数的参数类型:
const fns: FuncMap = { f1: () => {}, f2: (a: string) => {}, f3: (a: string, b: string) => {} }; // 用Parameters工具类型自动推导每个函数的参数数组类型 const argsArr: { [K in keyof FuncMap]: Parameters<FuncMap[K]> } = { f1: [], f2: ['str'], f3: ['foo', 'bar'] // 注意:你原来的[1,2]不符合f3的string参数类型,这里修正 };
步骤3:泛型约束的run函数
通过泛型K收窄name为具体的函数名称,TypeScript会自动推断出对应函数和参数的匹配类型:
function run<K extends keyof FuncMap>(name: K) { const fn = fns[name]; const args = argsArr[name]; fn(...args); // 无编译错误,类型完全匹配 }
关于通用函数装饰器的类型定义
你提到的非TS装饰器(即函数式装饰器),可以定义成通用的类型,接收任意函数并返回同类型的函数:
// 通用函数装饰器类型:接收任意函数,返回同签名的函数 type FunctionDecorator = <F extends (...args: any[]) => any>(fn: F) => F; // 示例:实现一个打印参数的装饰器 const logArgs: FunctionDecorator = (fn) => { return (...args) => { console.log('执行参数:', args); return fn(...args); }; }; // 使用示例 const decoratedF2 = logArgs(fns.f2); decoratedF2('test'); // 输出:执行参数: ["test"]
内容的提问来源于stack exchange,提问作者Denis
相关产品推荐
相关产品推荐

