TypeScript 工具类型

开发中常需要从已有类型派生出新类型:属性全变可选、挑出几个字段、补全必填……TypeScript 内置了一批泛型工具类型,一次调用即可完成常见类型变换,省去大量重复的类型声明。

Partial / Required / Readonly

三者分别把类型属性变为可选、必填、只读:

interface Todo {
  title: string;
  done: boolean;
}

type PartialTodo = Partial<Todo>;         // { title?: string; done?: boolean }
type RequiredTodo = Required<PartialTodo>; // 全部恢复必填
type ReadonlyTodo = Readonly<Todo>;       // 属性全部只读

const update: PartialTodo = { title: "学习" }; // 只传需要改的字段
console.log(update); // 输出:{ title: '学习' }

Partial 常用于「更新接口只传要改的字段」,Readonly 常用于不可变的配置。

Pick / Omit:挑选与剔除

Pick 选出指定属性,Omit 剔除指定属性:

interface Person {
  name: string;
  age: number;
  email: string;
}

type NameOnly = Pick<Person, "name" | "age">; // 只保留 name、age
type NoEmail = Omit<Person, "email">;          // 去掉 email

const info: NameOnly = { name: "王五", age: 30 };
console.log(info); // 输出:{ name: '王五', age: 30 }

列表页用 Pick 拿轻量字段,提交表单用 Omit 排除服务端生成的字段。

Record:构造对象类型

Record<K, V> 用键类型 K 构造字典,值类型为 V:

type Status = "pending" | "done" | "failed";

const map: Record<Status, string> = {
  pending: "进行中",
  done: "已完成",
  failed: "失败"
};
console.log(map.done); // 输出:已完成

Record 要求所有键写全,漏掉某个状态会立刻编译报错,适合做枚举映射表。

Exclude / Extract / NonNullable

Exclude 从联合中剔除成员,Extract 取出交集成员,NonNullable 去掉 null/undefined:

type T1 = Exclude<"a" | "b" | "c", "a">;         // "b" | "c"
type T2 = Extract<"a" | "b", "a" | "b" | "c">;   // "a" | "b"
type T3 = NonNullable<string | null | undefined>; // string

let x: T1 = "b";
// x = "a"; // 报错:已经不在联合类型里

type Key = Exclude<keyof Todo, "done">; // "title":动态剔除键

Exclude<keyof T, K> 与映射类型组合,正是 Omit 等工具的底层实现思路。

小结:Partial、Pick、Record、Exclude 等工具类型把常见变换封装成一行调用,配合 keyof、泛型与映射类型使用,可大幅减少重复的类型声明。

笔记加载中…