复合类型
类型的组合
元组类型的形式如同数组:
type Point = [number, number]
number 值作为一个元组传递。上述的 Point 类型表示二维坐标系中的 x 和 y,我们也可通过元组表示三维空间中的点:
type Point = [number, number, number]
除了表示三维空间中的点,也可以用来表示矩阵或张量等:
// 2x2 矩阵(二阶张量)
type Matrix2x2 = [[number, number], [number, number]]
// 或者更通用的矩阵类型
type Matrix = number[][]
通过类和泛型可以实现特定的元组:
class Pair<T1, T2> {
x: T1
y: T2
constructor(x: T1, y: T2) {
this.x = x
this.y = y
}
}
type Point = Pair<number, number>
// 或
class Pair<T1, T2> {
constructor(public x: T1, public y: T2) {}
}
class Point extends Pair<number, number> {
constructor(x: number, y: number) {
super(x, y)
}
}
// 或
interface Pair<T1, T2> {
x: T1
y: T2
}
type Point = Pair<number, number>
使用 interface 的实现更轻量,适合仅定义类型的场景。
注意
class Pair<T1, T2> {
constructor(public x: T1, public y: T2) {}
}
class Pair<T1, T2> {
x: T1
y: T2
constructor(x: T1, y: T2) {
this.x = x
this.y = y
}
}

执行顺序: 1. new Point(1, 2) 被调用 2. 进入 Point 的构造函数 3. 调用 super(1, 2),执行父类 Pair 的构造函数 4. 父类构造函数中,public x: T1 和 public y: T2 会自动执行 this.x = 1 和 this.y = 2 5. 返回后,Point 实例的 x 和 y 已被设置
类型组合成多选一类型
通过类型表达多选一,可以通过枚举实现:
enum DayOfWeek {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
上述枚举作为参数时很好用,当函数处理过后,返回值可能是枚举或 undefined,这时可以通过 | 实现这种行为:
function getDayOfWeek(input: string): DayOfWeek | undefined {}
代数数据类型
代数数据类型(ADT)是类型系统中组合类型的方式。它包括两种组合方式:乘积类型与和类型。
乘积类型(Product Type)
乘积类型表示”同时拥有”多个类型的值,例如元组类型 [Two, Three] 表示同时拥有 Two 类型和 Three 类型的值。
例如给定 enum Two {A, B} 和 enum Three {C, D, E},元组类型 [Two, Three] 这一类型就是乘积类型。
计算方式:乘积类型的可能值数量 = 第一个类型的可能值数量 × 第二个类型的可能值数量
Two有 2 个可能值:A, BThree有 3 个可能值:C, D, E[Two, Three]的所有可能组合:- [A, C], [A, D], [A, E]
- [B, C], [B, D], [B, E]
- 总共:2 × 3 = 6 种可能值
和类型(Sum Type)
和类型表示”或者”的关系,例如联合类型 Two | Three 表示值可以是 Two 类型或者 Three 类型。
给定 enum Two {A, B} 和 enum Three {C, D, E},类型 Two | Three 这一类型是和类型。
计算方式:和类型的可能值数量 = 第一个类型的可能值数量 + 第二个类型的可能值数量
Two的值:A, BThree的值:C, D, ETwo | Three的所有可能值:A, B, C, D, E- 总共:2 + 3 = 5 种可能值
总结
- 乘积类型:表示”同时拥有”,使用乘法计算(2 × 3 = 6)
- 和类型:表示”或者”,使用加法计算(2 + 3 = 5)
注意⚠️:代数数据类型所要传达的含义是每种类型可能的值有多少种情况,也就是可能的集合是什么样的。
| 表示联合类型,等价于代数类型中的和类型。& 是交集类型,不是代数类型中的乘积类型,元组是代数类型中的乘积类型。
TypeScript 使用的是结构类型系统(Structural Typing),而不是名义类型系统(Nominal Typing)。这使得 & 的行为与数学中的集合交集不完全相同。
数学视角:A ∩ B 要求元素”同时属于A和B”,TypeScript视角:A & B 要求元素”同时满足A和B的结构约束”。
& 更像是约束合并而非交集
函数类型的特殊行为:
type F1 = (x: number) => number;
type F2 = (x: string) => string;
// TypeScript:F1 & F2 = 函数重载
type F = F1 & F2;
// 实际上这是可能的:
const f: F = <T extends unknown>(x: T): T => {
if (typeof x === "number") return (x * 2) as T;
if (typeof x === "string") return x.toUpperCase() as T;
throw new Error("Unsupported type");
} as F;