使用扩展运算符时rest为TS联合元组类型,如何解决TS(2556)报错?
解决TypeScript中联合函数类型参数展开的TS(2556)报错
问题场景
你定义了两个参数类型不同的函数,随后编写了一个接收这两个函数联合类型的高阶函数,试图返回匹配对应参数的函数,但在展开rest参数时触发TS(2556)警告,代码如下:
function a(val: string) { console.log(val); } function b(val: boolean) { console.log(val); } function func(fn: typeof a | typeof b) { return (...rest: Parameters<typeof fn>) => { fn(...rest); // 此处触发TS(2556)错误 }; }
报错原因
当fn是typeof a | typeof b联合类型时,Parameters<typeof fn>会解析为[string] | [boolean]的联合元组。TypeScript无法确定传入的rest参数到底匹配联合类型中的哪一个函数的参数,因此会判定展开操作类型不安全,抛出错误。
解决方案:用泛型约束具体函数类型
将func改为泛型函数,让TypeScript能追踪传入fn的具体类型,而非停留在联合类型层面:
function a(val: string) { console.log(val); } function b(val: boolean) { console.log(val); } function func<T extends typeof a | typeof b>(fn: T) { return (...rest: Parameters<T>) => { fn(...rest); // 错误消失 }; }
原理说明
泛型T会捕获传入fn的具体类型(要么是typeof a,要么是typeof b),此时Parameters<T>会对应到具体的元组类型([string]或[boolean]),TypeScript能明确rest参数和fn的参数类型完全匹配,因此不再触发类型错误。
如果需要更通用的写法,也可以用泛型约束所有函数类型:
function func<T extends (...args: any[]) => any>(fn: T) { return (...rest: Parameters<T>) => { return fn(...rest); }; }
这种写法适配任意参数类型的函数,都能正确推导返回函数的参数类型。
内容的提问来源于stack exchange,提问作者why do i have so much question
相关产品推荐
相关产品推荐

