文章目录
- 联合类型(Union Types)
- 交叉类型(Intersection Types)
联合类型(Union Types)
联合类型(Union Types)是 TypeScript 中的一种高级类型,它允许一个变量可以存储多种类型的值。具体来说,联合类型用 |
符号将多个类型进行组合。例如,string | number
表示该变量可以存储字符串或数字类型的值。
联合类型的特点是灵活多样,可以应对不同的数据类型。它允许我们在某个位置期望多个可能的类型,并根据实际情况使用不同的类型。
优点:
- 提供了更灵活的数据类型定义,适用于不确定变量类型的情况。
- 可以避免使用 any 类型,提高类型安全性。
- 有效地支持方法重载和函数重载。
缺点:
- 在使用联合类型时,我们需要进行额外的类型检查和类型保护,以确保代码的正常运行。
- 可能增加代码复杂性,需要根据不同类型进行逻辑处理。
应用场景:
- 当一个变量可能有多种类型时,可以使用联合类型进行定义。
- 在不确定一个变量的具体类型时,可以使用联合类型进行类型保护。
- 用于方法重载和函数重载,以支持不同类型的参数和返回值。
下面是一个简单的代码案例,展示了如何使用联合类型:
function printValue(value: string | number): void {
console.log(value);
}
// 调用 printValue 函数
printValue("hello"); // 输出:hello
printValue(123); // 输出:123
在上述案例中,printValue
函数的参数 value
的类型是 string | number
,它可以接收字符串或数字类型的值。通过使用联合类型,我们可以灵活地调用并传递不同类型的值。
需要注意的是,当我们在使用联合类型的值时,需要进行类型检查和类型保护。这可以通过类型断言、类型保护函数、typeof 和 instanceof 运算符来实现。
当涉及到联合类型时,我们必须注意如何进行类型保护,以确保安全地操作变量。以下是几个使用联合类型的代码案例,并展示了不同的类型保护方法:
案例1: 类型断言
function printValue(value: string | number): void {
if (typeof value === "string") {
// 使用类型断言,将 value 视为字符串类型
console.log(value.toUpperCase());
} else {
// 使用类型断言,将 value 视为数字类型
console.log(value.toFixed(2));
}
}
printValue("hello"); // 输出:HELLO
printValue(3.14159); // 输出:3.14
案例2: 类型保护函数
// 定义类型保护函数,判断是否为字符串
function isString(value: string | number): value is string {
return typeof value === "string";
}
function printValue(value: string | number): void {
if (isString(value)) {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
printValue("hello"); // 输出:HELLO
printValue(3.14159); // 输出:3.14
案例3: typeof 和 instanceof 运算符
function printValue(value: string | number): void {
if (typeof value === "string") {
console.log(value.toUpperCase());
} else if (value instanceof Number) {
console.log(value.toFixed(2));
}
}
printValue("hello"); // 输出:HELLO
printValue(new Number(3.14159)); // 输出:3.14
案例4: switch 语句
function printValue(value: string | number): void {
switch (typeof value) {
case "string":
console.log(value.toUpperCase());
break;
case "number":
console.log(value.toFixed(2));
break;
}
}
printValue("hello"); // 输出:HELLO
printValue(3.14159); // 输出:3.14
在这些案例中,我们通过不同的方法进行了类型保护。在每个条件分支中,我们根据变量的类型来执行相应的操作。这样可以确保在类型不一致的情况下,代码能够正确地进行类型处理。需要根据具体的场景选择适合的类型保护方法。
交叉类型(Intersection Types)
TypeScript 的交叉类型(Intersection Types)是将多个类型合并为一个新的类型的一种方式。通过交叉类型,可以创建一个包含了多个类型特性的类型。下面是关于交叉类型的概念、特点、优缺点和应用场景的解释,以及几个代码案例。
-
概念:交叉类型是通过使用 “&” 符号来表示的。它表示一个新类型,该类型包含了多个类型的特性,即所有类型的并集。例如,类型 A & B 表示一个包含类型 A 和类型 B 特性的新类型。
-
特点:
- 交叉类型将多个类型的特性进行合并,使得新类型具备了所有原始类型的特性。
- 交叉类型可以用于定义对象、函数和类的类型。
- 交叉类型可以结合其他
TypeScript
的类型特性(比如联合类型、泛型)一起使用。
-
优缺点:
- 优点:交叉类型使得可以将多个类型的特性组合在一起,增加了类型的灵活性和复用性。
- 缺点:如果交叉的多个类型之间有冲突,可能会导致类型的不一致。
-
应用场景:
- 用于定义具有多个类型特性的对象、函数或类。
- 用于组合已经存在的类型,以创建新的复合类型。
下面是几个代码案例,展示了交叉类型的使用:
案例 1:合并对象属性
type Person = {
name: string;
age: number;
};
type Employee = {
id: number;
salary: number;
};
type EmployeePerson = Person & Employee;
const employee: EmployeePerson = {
name: "John",
age: 30,
id: 1,
salary: 5000,
};
案例 2:合并函数参数和返回值
type Order = {
id: number;
quantity: number;
};
type DiscountedOrder = Order & {
discount: number;
};
function applyDiscount(order: DiscountedOrder): number {
return order.quantity * order.discount;
}
const order: DiscountedOrder = {
id: 1,
quantity: 5,
discount: 0.1,
};
const discountedAmount = applyDiscount(order);
console.log(discountedAmount); // 输出:0.5
案例 3:合并类的方法
class A {
methodA() {
console.log("Method A");
}
}
class B {
methodB() {
console.log("Method B");
}
}
type CombinedClass = A & B;
const obj: CombinedClass = new CombinedClass();
obj.methodA(); // 输出:Method A
obj.methodB(); // 输出:Method B
案例 4:组合联合类型和交叉类型
type Dog = {
type: "dog";
bark: () => void;
};
type Cat = {
type: "cat";
meow: () => void;
};
type Animal = Dog | Cat;
type Pet = Animal & {
name: string;
};
function playWithPet(pet: Pet) {
if (pet.type === "dog") {
pet.bark();
} else if (pet.type === "cat") {
pet.meow();
}
}
const pet: Pet = {
type: "cat",
name: "Kitty",
meow: () => console.log("Meow"),
};
playWithPet(pet); // 输出:Meow
这些案例展示了交叉类型的不同应用场景和特点。通过使用交叉类型,可以组合多个类型的特性,创建出更灵活、复合的类型。