第 13 章:工具类型
学习目标
- 掌握 TS 内置工具类型 Partial / Required / Pick 等
- 学会 Record / Readonly / Exclude
- 理解 ReturnType / Parameters / Awaited
- 实战构建自定义工具类型
一、Partial<T>(全部可选)
typescript
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>;
// 等价于:
// { id?: number; name?: string; email?: string }
const u: PartialUser = {}; // ✅
u.name = 'Tom'; // ✅二、Required<T>(全部必选)
typescript
interface Config {
host?: string;
port?: number;
}
type RequiredConfig = Required<Config>;
// { host: string; port: number }三、Readonly<T>(全部只读)
typescript
type ReadonlyUser = Readonly<User>;
const u: ReadonlyUser = { id: 1, name: 'Tom', email: 'a@b.com' };
u.name = 'Jerry'; // ❌ Cannot assign四、Pick<T, K>(挑字段)
typescript
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: number; name: string }五、Omit<T, K>(剔字段)
typescript
type UserWithoutEmail = Omit<User, 'email'>;
// { id: number; name: string }六、Record<K, V>(构造对象类型)
typescript
type Role = 'admin' | 'user' | 'guest';
type RoleMap = Record<Role, number>;
// { admin: number; user: number; guest: number }
const perms: RoleMap = {
admin: 100,
user: 10,
guest: 1,
};⚠️ 坑 1:
Record<K, V>要求K是联合字面量类型或string/number/symbol,否则推导不到完整 keys。
七、Exclude<T, U>(排除)
typescript
type T = Exclude<'a' | 'b' | 'c', 'a' | 'b'>; // 'c'
type U = Exclude<string | number | boolean, boolean>; // string | number八、Extract<T, U>(提取)
typescript
type T = Extract<'a' | 'b' | 'c', 'a' | 'b'>; // 'a' | 'b'
type U = Extract<string | number, number>; // number九、NonNullable<T>(去除 null/undefined)
typescript
type T = NonNullable<string | null | undefined>; // string十、ReturnType<T>(返回值类型)
typescript
function getUser() {
return { id: 1, name: 'Tom' };
}
type R = ReturnType<typeof getUser>;
// { id: number; name: string }十一、Parameters<T>(参数类型)
typescript
function createUser(name: string, age: number): void {}
type P = Parameters<typeof createUser>; // [name: string, age: number]十二、Awaited<T>(解 Promise)
typescript
type A = Awaited<Promise<string>>; // string
type B = Awaited<Promise<Promise<number>>>; // number十三、自定义工具类型
1. Nullable<T>
typescript
type Nullable<T> = T | null;
type S = Nullable<string>; // string | null2. Mutable<T>(去掉 readonly)
typescript
type Mutable<T> = {
-readonly [K in keyof T]: T[K];
};3. PickByValue<T, V>(挑出值类型为 V 的字段)
typescript
type PickByValue<T, V> = {
[K in keyof T as T[K] extends V ? K : never]: T[K];
};
interface User {
id: number;
name: string;
age: number;
}
type StringProps = PickByValue<User, string>;
// { name: string }4. Optional<T, K>(指定字段可选)
typescript
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type U = Optional<User, 'email'>;
// { id: number; name: string; email?: string }⚠️ 坑 2:工具类型类型参数有顺序:
Pick<T, K>第一是对象,第二是 key 联合;Record<K, V>第一是 key,第二是 value。记混了排查浪费时间。
十四、本章小结
| 工具类型 | 作用 |
|---|---|
| Partial / Required | 全部可选 / 必选 |
| Readonly | 全部只读 |
| Pick / Omit | 挑 / 剔字段 |
| Record | 构造对象类型 |
| Exclude / Extract | 排除 / 提取联合 |
| NonNullable | 去除 null/undefined |
| ReturnType / Parameters | 函数返回值 / 参数 |
| Awaited | 解 Promise |
动手练习
- Partial 实战:定义
User,写updateUser(id, patch: Partial<User>)函数 - Pick 实战:用
Pick从User中挑出id和name,作为列表项类型 - 自定义:实现
MaybePromise<T> = T | Promise<T>,常用于"既可同步又可异步"的接口
下一章:第 14 章:高级类型 →