深入理解TypeScript类型系统,掌握高级类型编程技巧
TypeScript高级特性详解
本文将深入介绍TypeScript的高级特性和类型编程技巧,帮助你更好地利用TypeScript的类型系统。
泛型高级用法
- 泛型约束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
// 正确
loggingIdentity("hello");
loggingIdentity([1, 2, 3]);
// 错误
loggingIdentity(3); // 数字没有length属性
|
- 泛型工具类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
// Partial - 使所有属性可选
interface Todo {
title: string;
description: string;
}
type PartialTodo = Partial<Todo>;
// 等同于
// {
// title?: string;
// description?: string;
// }
// Record - 构造键值对类型
type PageInfo = {
title: string;
}
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = {
home: { title: "Home" },
about: { title: "About" },
contact: { title: "Contact" }
};
|
高级类型
- 映射类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}
// 使用示例
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
type NameOnly = Pick<Person, "name">;
|
- 条件类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
type NonNullable<T> = T extends null | undefined ? never : T;
// 使用示例
type T1 = NonNullable<string | number | undefined>; // string | number
type T2 = NonNullable<string[] | null | undefined>; // string[]
// 分布式条件类型
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
|
类型推断
- 类型推导
1
2
3
4
5
6
7
|
// 返回类型推导
function createPair<S, T>(v1: S, v2: T): [S, T] {
return [v1, v2];
}
// TypeScript能够推导出返回类型
const pair = createPair("hello", 42); // [string, number]
|
- 类型保护
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function getSmallPet(): Fish | Bird {
// ...
return {} as Fish | Bird;
}
let pet = getSmallPet();
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
|
装饰器
- 类装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
function classDecorator<T extends { new (...args: any[]): {} }>(
constructor: T
) {
return class extends constructor {
newProperty = "new property";
hello = "override";
};
}
@classDecorator
class Greeter {
property = "property";
hello: string;
constructor(m: string) {
this.hello = m;
}
}
|
- 方法装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
let originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
return originalMethod.apply(this, args);
};
return descriptor;
}
class Calculator {
@log
add(x: number, y: number) {
return x + y;
}
}
|
高级实践
- 类型体操
1
2
3
4
5
6
7
8
9
10
11
|
// 递归类型
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object
? DeepReadonly<T[P]>
: T[P];
}
// 联合转交叉
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends
((k: infer I) => void) ? I : never;
|
- 工具类型实现
1
2
3
4
5
6
7
8
9
10
|
// 提取Promise返回类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
// 获取函数返回类型
type ReturnType<T extends (...args: any) => any> =
T extends (...args: any) => infer R ? R : any;
// 获取构造函数实例类型
type InstanceType<T extends new (...args: any) => any> =
T extends new (...args: any) => infer R ? R : any;
|
最佳实践
- 类型定义规范
1
2
3
4
5
6
7
8
9
10
|
// 使用interface定义对象类型
interface User {
id: number;
name: string;
preferences?: UserPreferences;
}
// 使用type定义联合类型或工具类型
type ID = string | number;
type Nullable<T> = T | null;
|
- 类型断言最佳实践
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 优先使用as const
const config = {
endpoint: "api.example.com",
timeout: 3000
} as const;
// 避免使用any,使用unknown代替
function processValue(value: unknown) {
if (typeof value === "string") {
return value.toUpperCase();
}
return String(value);
}
|
掌握这些TypeScript高级特性,将帮助你写出更安全、可维护的TypeScript代码。