如何在不使用交集&的情况下合并含调用签名与属性的类型?
合并包含调用签名与属性的TypeScript类型(实现直观的单一结构展示)
在TypeScript中,直接使用交集运算符&合并包含调用签名和属性的类型时,结果会以Foo & { a: string } & { ()=>void } & Bar这类嵌套交叉的形式展示,可读性差且难以抽象。我们需要实现一种合并方式,让最终类型展示为{(a:string):number; (a:number):number; foo1:string; bar1:number}这种包含所有调用签名和属性的单一结构。
原代码的Merge工具类型仅通过keyof处理了对象属性,而调用签名不属于keyof的遍历范围,因此被遗漏,无法达到预期效果。
解决方案
我们需要拆分类型的两个核心部分分别处理:调用签名(包括多重载场景)和对象属性,再将两者合并。TypeScript会自动将调用签名与对象属性的交叉类型展开为直观的单一结构,无需手动干预展示形式。
完整实现代码如下:
// 提取类型中的函数调用签名部分 type ExtractCallable<T> = T extends (...args: any[]) => any ? T : never; // 提取类型中的非函数属性部分 type ExtractProperties<T> = Omit<T, keyof Function>; // 合并两个类型的调用签名(支持多重载) type MergeCallables<T1, T2> = (ExtractCallable<T1> extends never ? {} : ExtractCallable<T1>) & (ExtractCallable<T2> extends never ? {} : ExtractCallable<T2>); // 合并属性部分,重复键以T1的类型为准 type MergeProperties<T1, T2> = { [K in keyof ExtractProperties<T1> | keyof ExtractProperties<T2>]: K extends keyof T1 ? T1[K] : K extends keyof T2 ? T2[K] : never; }; // 最终的Merge工具类型 type Merge<T1, T2> = MergeCallables<T1, T2> & MergeProperties<T1, T2>; // 测试用例 type Foo = { (a: string): number; (a: number): number; foo1: string } type Bar = { bar1: number } type FooBar = Merge<Foo, Bar>;
此时FooBar的类型会直观展示为:
type FooBar = { (a: string): number; (a: number): number; foo1: string; bar1: number; }
内容的提问来源于stack exchange,提问作者TrevTheDev
相关产品推荐
相关产品推荐

