TypeScript 联合类型与交叉类型
联合类型与交叉类型是 TypeScript 类型组合的基础,下面梳理核心用法。
联合类型
使用 | 分隔,表示值可以是其中任意一种类型:
TypeScript
let id: string | number;
id = "abc"; // ✅
id = 123; // ✅
// id = true; // ❌
函数参数联合
TypeScript
function print(value: string | number): void {
console.log(value.toString());
}
print("hello"); // ✅
print(42); // ✅
注意:联合类型只能访问所有成员共有的属性或方法。
TypeScript
function getId(id: string | number): void {
// console.log(id.length); // ❌ number 没有 length
console.log(id.toString()); // ✅ 两者都有
}
类型守卫
缩小联合类型范围:
typeof 守卫
TypeScript
function padLeft(value: string, padding: string | number): string {
if (typeof padding === "number") {
return " ".repeat(padding) + value;
}
return padding + value;
}
instanceof 守卫
TypeScript
class Cat {
meow() { console.log("meow"); }
}
class Dog {
bark() { console.log("bark"); }
}
function handle(animal: Cat | Dog) {
if (animal instanceof Cat) {
animal.meow();
} else {
animal.bark();
}
}
in 守卫
TypeScript
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
function move(pet: Bird | Fish) {
if ("swim" in pet) {
pet.swim();
} else {
pet.fly();
}
}
字面量联合类型
TypeScript
type Direction = "up" | "down" | "left" | "right";
function move(dir: Direction) {
console.log(`Moving ${dir}`);
}
move("up"); // ✅
// move("forward"); // ❌
交叉类型
使用 & 合并多个类型的所有属性:
TypeScript
interface ErrorInfo {
message: string;
code: number;
}
interface LocationInfo {
file: string;
line: number;
}
type DetailedError = ErrorInfo & LocationInfo;
const err: DetailedError = {
message: "Unexpected token",
code: 1001,
file: "index.ts",
line: 42
};
混合类型
TypeScript
type Draggable = {
drag(): void;
};
type Resizable = {
resize(): void;
};
type Widget = Draggable & Resizable;
class MyWidget implements Widget {
drag() { console.log("Dragging"); }
resize() { console.log("Resizing"); }
}
交叉类型冲突处理
相同属性名但不同类型时,交叉结果为 never:
TypeScript
interface A {
value: string;
}
interface B {
value: number;
}
type AB = A & B;
// AB 的 value 类型为 string & number(即 never)
注意:实际开发中应避免同名属性冲突。
要点总结
- 联合类型
|表示值可能是多种类型之一 - 联合类型只能访问所有成员共有的属性,需用类型守卫缩小范围
typeof/instanceof/in是常用类型守卫- 交叉类型
&合并多个类型的所有属性 - 同名属性冲突会导致类型为
never,应避免
📝 发现内容有误?点击此处直接编辑