TypeScript 高级类型
TypeScript 高级类型是 TypeScript 类型系统中的一些高级特性和技巧,用于编写更复杂和灵活的代码。以下是 TypeScript 高级类型的详细介绍,包括交叉类型、联合类型、类型别名、类型断言、字面量类型、可辨识联合、类型守卫、映射类型和条件类型。
1. 交叉类型(Intersection Types)
交叉类型 A & B
表示同时是 A
和 B
类型的类型。它通常用于将多个类型的成员结合在一起。
interface Person {
name: string;
}
interface Employee {
employeeId: number;
}
type Staff = Person & Employee;
const staffMember: Staff = {
name: "John",
employeeId: 123
};
2. 联合类型(Union Types)
联合类型 A | B
表示可以是 A
或 B
类型的类型。它通常用于表示一个值可以有多种类型。
function printId(id: number | string) {
console.log(`ID: ${id}`);
}
printId(123);
printId("abc");
3. 类型别名(Type Aliases)
类型别名用于给类型起一个新的名字。它可以简化复杂类型的使用。
type StringOrNumber = string | number;
let value: StringOrNumber;
value = "hello";
value = 42;
4. 字面量类型(Literal Types)
字面量类型允许你指定一个变量只能有特定的值。它通常与联合类型结合使用来实现枚举的效果。
type Direction = "up" | "down" | "left" | "right";
function move(direction: Direction) {
console.log(`Moving ${direction}`);
}
move("up");
// move("forward"); // Error: Argument of type '"forward"' is not assignable to parameter of type 'Direction'.
5. 可辨识联合(Discriminated Unions)
可辨识联合是 TypeScript 中的一种模式,用于类型安全地处理联合类型。它通常由联合类型、字面量类型和类型守卫结合实现。
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Rectangle | Circle;
function area(shape: Shape): number {
switch (shape.kind) {
case "square":
return shape.size * shape.size;
case "rectangle":
return shape.width * shape.height;
case "circle":
return Math.PI * shape.radius * shape.radius;
default:
return 0;
}
}
6. 类型守卫(Type Guards)
类型守卫是一些表达式,用于在运行时检查类型,并在特定的代码块中缩小类型范围。常见的类型守卫包括 typeof
、instanceof
和自定义类型谓词。
function isString(value: any): value is string {
return typeof value === "string";
}
function print(value: string | number) {
if (isString(value)) {
console.log(`String: ${value}`);
} else {
console.log(`Number: ${value}`);
}
}
7. 映射类型(Mapped Types)
映射类型用于基于旧类型创建新类型。它遍历旧类型的属性,并基于其创建新的类型。
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
const person: ReadonlyPerson = { name: "Alice", age: 30 };
// person.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.
8. 条件类型(Conditional Types)
条件类型用于根据某个条件表达式生成不同的类型。
type TypeName<T> = T extends string
? "string"
: T extends number
? "number"
: T extends boolean
? "boolean"
: T extends undefined
? "undefined"
: T extends Function
? "function"
: "object";
type T1 = TypeName<string>; // "string"
type T2 = TypeName<number>; // "number"
type T3 = TypeName<boolean>; // "boolean"
type T4 = TypeName<() => void>; // "function"
type T5 = TypeName<object>; // "object"
9. 索引类型(Index Types)
定义:索引类型用于获取对象属性的类型。
用法:使用 keyof
和索引访问操作符 T[K]
。
interface Person {
name: string;
age: number;
}
type PersonKeys = keyof Person; // "name" | "age"
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
let person: Person = { name: "Alice", age: 30 };
let name: string = getValue(person, "name"); // OK
// let invalid = getValue(person, "invalid"); // Error: Argument of type '"invalid"' is not assignable to parameter of type 'keyof Person'.
说明:keyof
操作符获取对象的键,T[K]
获取对象属性的类型。
高级类型示例
结合使用多个高级类型特性可以创建更复杂的类型定义。
type ApiResponse<T> = {
data: T;
error: string | null;
status: number;
};
type User = {
id: number;
name: string;
email: string;
};
type UserResponse = ApiResponse<User>;
const response: UserResponse = {
data: { id: 1, name: "John Doe", email: "john.doe@example.com" },
error: null,
status: 200,
};
高级类型总结
TypeScript 高级类型提供了一些强大而灵活的工具,用于创建复杂且类型安全的代码。通过理解和利用这些特性,你可以编写更健壮和可维护的 TypeScript 代码。以下是关键点:
- 交叉类型:将多个类型合并为一个类型。
- 联合类型:表示值可以是多种类型之一。
- 类型别名:给复杂类型起一个简洁的名字。
- 字面量类型:指定变量只能有特定的值。
- 可辨识联合:安全处理联合类型。
- 类型守卫:在运行时检查并缩小类型范围。
- 映射类型:基于旧类型创建新类型。
- 条件类型:根据条件生成不同的类型。
通过掌握这些高级类型特性,你可以更加灵活和精确地描述代码中的数据结构和行为。