文章目录
一、TypeScript 联合类型
在 TypeScript 中,联合类型(Union Types)允许你将多个类型组合成一个类型。一个变量可以是这些类型中的任何一个。联合类型通常用于表示一个值可以是几种类型之一的情况。
下面是一个简单的例子,展示了如何定义和使用联合类型:
let value: string | number;
value = "Hello"; // OK
value = 42; // OK
// 访问联合类型变量的属性或方法时,需要确保该属性或方法在所有类型上都可用
// 或者在访问之前使用类型守卫(type guards)来缩小类型范围
if (typeof value === "string") {
console.log(value.length); // OK,因为此时value是string类型
} else if (typeof value === "number") {
console.log(value.toFixed(2)); // OK,因为此时value是number类型
}
// 试图访问一个不是所有类型都共有的属性或方法会导致编译错误
// console.log(value.length); // Error if value is a number
// 另一种处理联合类型的方式是使用类型断言
// 但请注意,类型断言会绕过 TypeScript 的类型检查,应谨慎使用
if (value as string).length > 0) {
// 这里假设了value是string类型,如果它不是,运行时可能会出错
}
// 或者使用用户自定义的类型守卫
function isString(val: any): val is string {
return typeof val === "string";
}
if (isString(value)) {
console.log(value.length); // OK
}
在上面的例子中,value
被定义为 string | number
的联合类型。这意味着 value
可以是 string
类型,也可以是 number
类型。当我们尝试访问 value
的属性或方法时,需要确保这些属性或方法在所有可能的类型上都是可用的,或者使用类型守卫来缩小 value
的类型范围。
类型守卫是一种表达式,它返回一个类型谓词,即一个返回类型为 type is T
的函数,其中 T
是某个类型。在上面的例子中,isString
函数就是一个类型守卫,它用于检查一个值是否是 string
类型。如果 isString(value)
返回 true
,那么 TypeScript 就知道在随后的代码块中,value
一定是 string
类型。
二、TypeScript 联合类型数组
在 TypeScript 中,联合类型不仅适用于单个变量,还可以应用于数组。当你有一个数组,其中的元素可以是多种类型之一时,你可以使用联合类型来定义这个数组。
以下是一个示例,展示了如何定义和使用包含联合类型元素的数组:
// 定义一个联合类型,表示数组中的元素可以是 string 或 number
type StringOrNumberArray = Array<string | number>;
// 创建一个符合这个联合类型定义的数组
let array: StringOrNumberArray = [1, 2, "three", 4, "five"];
// 遍历数组并处理元素
for (let item of array) {
if (typeof item === "string") {
console.log(`字符串: ${item}`);
} else if (typeof item === "number") {
console.log(`数字: ${item}`);
}
}
// 试图将不符合联合类型的值推入数组会导致编译错误
// array.push(true); // Error: 类型 'boolean' 的参数不能赋给类型 'string | number' 的参数
// 使用类型守卫或类型断言来缩小类型范围
function isString(item: any): item is string {
return typeof item === "string";
}
for (let item of array) {
if (isString(item)) {
// 在这个分支中,item 已经被缩小为 string 类型
console.log(`字符串长度: ${item.length}`);
}
}
在上面的示例中,StringOrNumberArray
是一个联合类型数组,其元素可以是 string
或 number
类型。我们创建了一个符合这个类型的数组 array
,并遍历它来处理不同类型的元素。在遍历过程中,我们使用 typeof
操作符来检查每个元素的类型,并根据类型执行不同的操作。
我们还定义了一个 isString
类型守卫函数,它用于在运行时检查一个值是否是 string
类型。在 for
循环中,我们使用这个类型守卫来缩小 item
的类型范围,以便在相应的分支中安全地访问字符串的 length
属性。
最后,我们尝试将一个布尔值 true
推入数组 array
,但由于它不符合 string | number
的联合类型,TypeScript 编译器会报错。
三、联合类型有哪些应用场景
联合类型在 TypeScript 中的应用场景广泛,主要用于处理变量、参数或返回值可能具有多种类型的情况。以下是几个具体的应用场景及案例:
1. 处理不确定类型的变量:
当你不确定一个变量的具体类型时,可以使用联合类型。例如,你可能有一个变量,它可能是字符串或数字,取决于某些条件。
let value: string | number;
if (someCondition) {
value = "Hello";
} else {
value = 42;
}
console.log(value);
2. 函数参数和返回值的类型:
在定义函数时,如果函数的参数或返回值可能有多种类型,可以使用联合类型。
function printValue(value: string | number): void {
console.log(value);
}
printValue("Hello"); // 输出: Hello
printValue(42); // 输出: 42
3. 定义明确成员的集合:
联合类型还可以用于定义具有明确成员的集合,例如表示方向的枚举。
type Direction = "north" | "east" | "south" | "west";
function getDirectionFirstLetter(direction: Direction): string {
return direction.charAt(0);
}
getDirectionFirstLetter("east"); // 输出: e
4. 类型断言:
当使用联合类型的变量时,有时需要告诉 TypeScript 具体的类型,以便进行相应的操作。这时可以使用类型断言。
let variable: string | number;
variable = "123";
let length = (variable as string).length; // 当 variable 是字符串类型时,可以访问 length 属性
5. 结合字面量类型:
联合类型也可以与字面量类型结合使用,以创建更具体的类型定义。
type Status = "active" | "pending" | "completed";
function handleStatus(status: Status): void {
// ... 根据 status 的值执行相应的操作
}
handleStatus("active"); // 正确
handleStatus("invalid"); // 编译错误,因为 "invalid" 不是 Status 类型中的值
这些案例展示了联合类型在 TypeScript 中的灵活性和实用性,它们可以帮助你更精确地定义和处理具有多种可能类型的变量、参数和返回值。
四、相关链接
- TypeScript中文网
- TypeScript下载
- TypeScript文档
- 「TypeScript系列」TypeScript 简介及基础语法
- 「TypeScript系列」TypeScript 基础类型
- 「TypeScript系列」TypeScript 变量声明
- 「TypeScript系列」TypeScript 运算符
- 「TypeScript系列」TypeScript 条件语句
- 「TypeScript系列」TypeScript 循环
- 「TypeScript系列」TypeScript 函数
- 「TypeScript系列」TypeScript Number
- 「TypeScript系列」TypeScript String
- 「TypeScript系列」TypeScript Array(数组)
- 「TypeScript系列」TypeScript Map 对象
- 「TypeScript系列」TypeScript 元组