You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用交集&的情况下合并含调用签名与属性的类型?

合并包含调用签名与属性的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:03:26