技术
10 min readTypeScript 高级类型系统:从基础到精通
2025-01-18by LZG
#TypeScript#Frontend#Engineering
引言
TypeScript 的类型系统是其最强大的特性之一。从基础类型到高级类型,掌握这些概念可以帮助我们编写更安全、更可维护的代码。
1. 泛型 (Generics)
1.1 基础泛型
泛型允许我们编写可重用的组件,同时保持类型安全。
function identity<T>(arg: T): T {
return arg;
}
const num = identity<number>(42);
const str = identity("hello");
1.2 泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
1.3 泛型接口
interface Box<T> {
value: T;
}
const box: Box<string> = { value: "hello" };
2. 条件类型 (Conditional Types)
条件类型允许我们根据类型关系选择不同的类型。
2.1 基础语法
type IsArray<T> = T extends any[] ? true : false;
type A = IsArray<string[]>; // true
type B = IsArray<string>; // false
2.2 分布式条件类型
type ToArray<T> = T extends any ? T[] : never;
type StrArrOrNumArr = ToArray<string | number>;
// string[] | number[]
2.3 条件类型推断
type Flatten<T> = T extends infer U[] ? U : T;
type Flat = Flatten<number[][]>; // number
3. 映射类型 (Mapped Types)
映射类型允许我们基于现有类型创建新类型。
3.1 基础映射
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
3.2 添加修饰符
type Partial<T> = {
[P in keyof T]?: T[P];
};
type Required<T> = {
[P in keyof T]-?: T[P];
};
3.3 Key Remapping
type Getters<T> = {
[P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];
};
interface Person {
name: string;
age: number;
}
type PersonGetters = Getters<Person>;
// { getName: () => string; getAge: () => number }
4. 模板字面量类型
4.1 基础用法
type EventName<T extends string> = `on${Capitalize<T>}`;
type ClickEvent = EventName<"click">; // "onClick"
4.2 字符串操作类型
type Greeting<T extends string> = `Hello, ${T}!`;
type Message = Greeting<"World">; // "Hello, World!"
5. 实用工具类型
5.1 Pick 和 Omit
interface User {
id: number;
name: string;
email: string;
password: string;
}
type PublicUser = Pick<User, "id" | "name" | "email">;
type SafeUser = Omit<User, "password">;
5.2 Record
type UserRoles = Record<string, "admin" | "user" | "guest">;
const roles: UserRoles = {
alice: "admin",
bob: "user",
};
5.3 ReturnType
function getUser() {
return { id: 1, name: "Alice" };
}
type User = ReturnType<typeof getUser>;
6. 高级模式
6.1 递归类型
type Json =
| string
| number
| boolean
| null
| Json[]
| { [key: string]: Json };
const data: Json = {
name: "Alice",
age: 30,
tags: ["developer", "typescript"],
};
6.2 品牌类型
type Brand<T, B> = T & { __brand: B };
type USD = Brand<number, "USD">;
type EUR = Brand<number, "EUR">;
const usdAmount: USD = 100 as USD;
const eurAmount: EUR = 100 as EUR;
// 类型安全:不能直接相加
// const total = usdAmount + eurAmount; // Error
6.3 函数重载
function process(input: string): string;
function process(input: number): number;
function process(input: string | number): string | number {
if (typeof input === "string") {
return input.toUpperCase();
}
return input * 2;
}
7. 类型守卫
7.1 typeof 守卫
function processValue(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
7.2 instanceof 守卫
class Dog {
bark() { console.log("Woof!"); }
}
class Cat {
meow() { console.log("Meow!"); }
}
function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
7.3 自定义类型守卫
interface Bird {
type: "bird";
fly(): void;
}
interface Fish {
type: "fish";
swim(): void;
}
function isBird(animal: Bird | Fish): animal is Bird {
return animal.type === "bird";
}
function move(animal: Bird | Fish) {
if (isBird(animal)) {
animal.fly();
} else {
animal.swim();
}
}
8. 实战案例
8.1 API 响应类型
type ApiResponse<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
async function fetchUser(id: number): Promise<ApiResponse<User>> {
try {
const user = await api.getUser(id);
return { success: true, data: user };
} catch (error) {
return { success: false, error: error as Error };
}
}
8.2 表单验证类型
type ValidationRule<T> = {
validate: (value: T) => boolean;
message: string;
};
type FormField<T> = {
value: T;
rules: ValidationRule<T>[];
};
type FormSchema<T extends Record<string, any>> = {
[K in keyof T]: FormField<T[K]>;
};
结语
TypeScript 的高级类型系统为我们提供了强大的类型安全能力。通过掌握泛型、条件类型、映射类型等概念,我们可以编写出更加健壮和可维护的代码。关键是在实际项目中灵活运用这些技术,找到类型安全和开发效率的最佳平衡点。