Typescript(十二) 联合类型和交叉类型
TypeScript 联合类型(Union)和交叉类型(Intersection)是处理复杂类型的核心工具。
联合类型
值可以是多种类型中的 一种
let value: string | number;
value = "hello"; // ✅
value = 123; // ✅
value = true; // ❌ 报错
实际使用场景
函数参数多类型
function formatInput(input: string | number | Date): string {
if (typeof input === "string") {
return input.trim();
}
if (typeof input === "number") {
return input.toFixed(2);
}
return input.toISOString();
}
可空类型
function findUser(id: number): User | undefined {
// 找到返回 User,找不到返回 undefined
}
const user = findUser(1);
if (user) {
user.name; // ✅ 安全访问
}
字面量联合(枚举替代)
type Status = "pending" | "success" | "error";
type Direction = "up" | "down" | "left" | "right";
function setStatus(status: Status) {
// 只能传入这三个值
}
可辨识联合
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number }
| { kind: "triangle"; base: number; height: number };
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.side ** 2;
case "triangle":
return (shape.base * shape.height) / 2;
}
}
交叉类型
将多个类型 合并 为一个,包含所有类型的属性
简单示例
type A = { name: string };
type B = { age: number };
type Person = A & B; // { name: string; age: number }
const p: Person = { name: "张三", age: 25 };
实际使用场景
混入mixin模式
interface Loggable {
log(msg: string): void;
}
interface Serializable {
serialize(): string;
}
// 同时具有日志和序列化能力
class User implements Loggable & Serializable {
name = "张三";
log(msg: string) {
console.log(msg);
}
serialize() {
return JSON.stringify(this);
}
}
扩展已有类型
interface BaseConfig {
timeout: number;
retries: number;
}
interface WithCache {
cache: boolean;
ttl: number;
}
// 组合配置
type FullConfig = BaseConfig & WithCache;
const config: FullConfig = {
timeout: 5000,
retries: 3,
cache: true,
ttl: 60000,
};
给函数参数添加约束
function merge<T extends object, U extends object>(a: T, b: U): T & U {
return { ...a, ...b };
}
const result = merge({ name: "张三" }, { age: 25 });
// result: { name: string } & { age: number }
对比
| 联合 | 交叉 & | |
|---|---|---|
| 含义 | 或(多选一) | 与(全都要) |
| 属性 | 只能访问共有属性 | 可以访问所有属性 |
| 用途 | 参数多类型、状态枚举 | 类型组合、能力叠加 |
| 图示 | 并集的每个分支 | 交集的叠加 |
举例
// 联合:只能访问共有属性
type A = { name: string; a: number };
type B = { name: string; b: number };
type Union = A | B;
function test(u: Union) {
u.name; // ✅ 共有属性
u.a; // ❌ 报错,可能是 B
u.b; // ❌ 报错,可能是 A
}
// 交叉:可以访问所有属性
type Intersection = A & B; // { name: string; a: number; b: number }
function test2(i: Intersection) {
i.name; // ✅
i.a; // ✅
i.b; // ✅
}
评论区