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

TypeScript两种交叉类型展开方法的技术差异与输出对比

TypeScript 交叉类型展开:Expand vs Compute

这里的"解析"指将{ a: string } & { b: string }这类对象交叉类型转换为扁平化的{ a: string, b: string }结构。

1. @jcalz 的 Expand 类型

type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;

实现原理

通过条件类型推断将类型T复制到新类型变量O中,再通过恒等映射遍历并复制O的所有属性。条件类型推断本身是无操作,但它有两个关键作用:

  • 触发联合类型的分发特性
  • 强制编译器计算条件的"true"分支(如果去掉推断直接写{ [K in keyof T]: T[K] },编译器有时只会保留映射类型的原始形式,不会展开交叉类型)

2. Gabriel Vergnaud 的 Compute 类型

/**
 * Compute is a helper converting intersections of objects into
 * flat, plain object types.
 */
type Compute<T> = { [K in keyof T]: T[K] } & unknown

实现原理

先通过映射类型遍历T的属性,再与unknown进行交叉操作。unknown是TypeScript的顶级类型,与任何类型交叉都不会改变原类型,但这个操作会触发编译器对交叉类型进行扁平化计算。

两者的技术差异与适用场景

输出差异场景

  • 联合类型处理:Expand因为使用了条件类型推断,会对联合类型进行分发。比如Expand<{a: string} | {b: number}>会被处理为{a: string} | {b: number}(每个联合成员都被展开);而Compute不会分发联合类型,Compute<{a: string} | {b: number}>会直接返回等价于原联合类型的结果,但不会对每个成员单独展开。
  • 嵌套交叉类型:对于深层嵌套的交叉类型,两者都能展开,但Expand的推断机制在某些复杂嵌套场景下可能更稳定地触发展开;Compute的交叉unknown方式在极端嵌套情况下可能需要多次调用才能完全展开,不过大多数常规场景下两者效果一致。

性能对比

  • Expand:由于涉及条件类型推断和联合分发,在处理大规模联合类型或复杂嵌套类型时,可能会带来额外的类型计算开销,编译器需要逐个处理联合成员,性能略逊于Compute。
  • Compute:实现更简洁,仅通过映射加交叉unknown触发展开,没有联合分发的额外开销,在大多数场景下性能更优,尤其是处理非联合类型的交叉时。

内容的提问来源于stack exchange,提问作者Darryl Noakes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 23:01:32