什么是联合类型?
联合类型(Union Types)是TypeScript中一个强大的特性,它允许你将多个类型组合成一个类型。使用联合类型,一个值可以是几种类型之一。
基本语法
typescript
let value: string | number;
value = "hello"; // 正确
value = 42; // 正确
value = true; // 错误,布尔值不在联合类型中
实际应用场景
-
处理多种可能的输入类型:
typescriptfunction formatInput(input: string | number) { if (typeof input === "string") { return input.toUpperCase(); } return input.toFixed(2); }
-
描述可能为null或undefined的值:
typescriptlet maybeString: string | null = null; maybeString = "now it's a string";
什么是交叉类型?
交叉类型(Intersection Types)是将多个类型合并为一个类型,新类型将包含所有类型的特性。
基本语法
typescript
interface Person {
name: string;
age: number;
}
interface Employee {
company: string;
position: string;
}
type EmployeePerson = Person & Employee;
const john: EmployeePerson = {
name: "John",
age: 30,
company: "Tech Corp",
position: "Developer"
};
实际应用场景
-
组合多个对象类型:
typescriptfunction extend<T, U>(first: T, second: U): T & U { return { ...first, ...second }; }
-
混入(Mixin)模式:
typescriptclass Disposable { dispose() { console.log("Disposing..."); } } class Activatable { activate() { console.log("Activating..."); } } type SmartObject = Disposable & Activatable;
联合类型与交叉类型的区别
特性 | 联合类型 (Union) | 交叉类型 (Intersection) |
---|---|---|
语法 | `A | B` |
含义 | A或B | A且B |
可赋值性 | 只需满足其中一个 | 必须满足所有 |
类型推断 | 类型保护缩小范围 | 合并所有属性 |
高级用法
类型保护与联合类型
typescript
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
条件类型中的联合与交叉
typescript
type NonNullable<T> = T extends null | undefined ? never : T;
type Diff<T, U> = T extends U ? never : T;
type Filter<T, U> = T extends U ? T : never;
常见问题与解决方案
-
属性访问问题:
typescriptinterface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } function getSmallPet(): Fish | Bird { // ... } let pet = getSmallPet(); pet.layEggs(); // 没问题,两个接口都有 pet.swim(); // 错误,可能是Bird
解决方案:使用类型断言或类型保护
typescriptif ("swim" in pet) { pet.swim(); }
-
交叉类型中的属性冲突:
typescripttype Conflict = { a: number } & { a: string }; // a的类型变为 number & string,即 never
总结
联合类型和交叉类型是TypeScript类型系统中两个核心概念:
- 联合类型提供了灵活性,允许一个值属于多种类型之一
- 交叉类型提供了组合能力,可以创建包含多个类型特性的新类型
掌握这两种类型的使用方法,能够帮助你更精确地描述JavaScript代码中的复杂数据结构和行为,从而编写出更健壮、更易维护的TypeScript代码。