TypeScript:调用带泛型参数的映射函数时出现错误
问题:TypeScript泛型调用映射函数时的展开参数报错
我有一个TypeScript映射fnMap,其中包含参数类型不同的函数。想要创建一个泛型函数callFn,接收函数键与参数后调用映射中对应的函数,但运行代码时出现错误:A spread argument must either have a tuple type or be passed to a rest parameter. (2556)
报错代码如下:
function fnStr(str: string) {} function fnNum(num: number) {} const fnMap = { fnStr, fnNum } type FnMap = typeof fnMap; type FnKey = keyof FnMap type Fn<K extends FnKey> = FnMap[K] type FnArgs<K extends FnKey> = Parameters<Fn<K>> function callFn<K extends FnKey>(key: K, args: FnArgs<K>) { fnMap[key](...args) // <- 错误位置 }
解决方案
这个错误是因为TypeScript在泛型上下文里无法自动确认FnArgs<K>的元组类型——即便Parameters工具类型返回的是元组,泛型约束下编译器也没法精准推断。可以通过两种方式解决:
方式一:类型断言
通过类型断言告诉编译器,当前调用的函数可以接收对应的参数元组:
function callFn<K extends FnKey>(key: K, args: FnArgs<K>) { (fnMap[key] as (...args: FnArgs<K>) => void)(...args); }
方式二:改用Rest参数(推荐)
把callFn的参数改成rest形式,让编译器直接识别参数元组,同时调用方式更简洁:
function callFn<K extends FnKey>(key: K, ...args: FnArgs<K>) { fnMap[key](...args); } // 使用示例 callFn('fnStr', 'test string'); callFn('fnNum', 999);
这种方式更贴合TypeScript的类型推断逻辑,rest参数本身就是元组类型,编译器能直接匹配映射中函数的参数结构,不会再出现展开报错。
内容的提问来源于stack exchange,提问作者Mario Lamacchia
相关产品推荐
相关产品推荐

