Skip to content
第 13 章 前端 ⏱ 12 分钟阅读

第 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 | null

2. 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

动手练习 ​

  1. Partial 实战:定义 User,写 updateUser(id, patch: Partial<User>) 函数
  2. Pick 实战:用 Pick 从 User 中挑出 id 和 name,作为列表项类型
  3. 自定义:实现 MaybePromise<T> = T | Promise<T>,常用于"既可同步又可异步"的接口

下一章:第 14 章:高级类型 →

本站基于 VitePress 构建 · 由 StackHub 团队维护