全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-21 8 分钟 ✍️ juanwangdev

TypeScript 自定义复杂工具类型

组合条件类型与映射类型可封装业务专用工具类型,下面梳理核心用法。

条件类型

基本语法 T extends U ? X : Y

TypeScript
type IsString<T> = T extends string ? "yes" : "no";

type A = IsString<string>;   // "yes"
type B = IsString<number>;   // "no"

提取返回类型

TypeScript
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function getUser() { return { id: 1, name: "Alice" }; }
type User = ReturnType<typeof getUser>;
// { id: number; name: string; }

映射类型

使用 in 遍历联合类型生成新对象类型:

TypeScript
type Options<T> = {
  [K in keyof T]?: T[K];
};

interface Config { host: string; port: number; }
type PartialConfig = Options<Config>;
// { host?: string; port?: number; }

键名映射

TypeScript
type Mutable<T> = {
  -readonly [K in keyof T]: T[K];
};

type Optional<T> = {
  [K in keyof T]-?: T[K];  // -? 移除可选
};

键名重映射

TypeScript
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface Person { name: string; age: number; }
type LazyPerson = Getters<Person>;
// { getName(): string; getAge(): number; }

组合条件与映射

过滤属性类型

TypeScript
type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

interface Mixed {
  name: string;
  age: number;
  active: boolean;
  count: number;
}

type NumberFields = PickByType<Mixed, number>;
// { age: number; count: number; }

可选与必填转换

TypeScript
type RequiredExcept<T, K extends keyof T> = Required<Omit<T, K>> & Pick<Partial<T>, K>;

interface Config {
  host: string;
  port?: number;
  timeout?: number;
}

// host 必填,port/timeout 可选
type Config2 = RequiredExcept<Config, "port" | "timeout">;

深层类型替换

TypeScript
type ReplaceType<T, From, To> = {
  [K in keyof T]: T[K] extends From ? To : T[K];
};

interface User {
  id: number;
  createdAt: Date;
  updatedAt: Date;
}

type StringDates = ReplaceType<User, Date, string>;
// { id: number; createdAt: string; updatedAt: string; }

实用工具类型封装

深度合并类型

TypeScript
type DeepMerge<T, U> = {
  [K in keyof T | keyof U]: K extends keyof T
    ? K extends keyof U
      ? T[K] extends object
        ? U[K] extends object
          ? DeepMerge<T[K], U[K]>
          : U[K]
        : U[K]
      : T[K]
    : K extends keyof U
      ? U[K]
      : never;
};

type A = { a: string; nested: { x: number } };
type B = { b: number; nested: { y: string } };
type Merged = DeepMerge<A, B>;
// { a: string; b: number; nested: { x: number; y: string } }

函数参数提取

TypeScript
type FirstParam<T extends (...args: any[]) => any> =
  T extends (arg: infer P, ...args: any[]) => any ? P : never;

type Fn = (name: string, age: number) => void;
type Name = FirstParam<Fn>;  // string

要点总结

  • 条件类型 T extends U ? X : Y 实现类型分支判断
  • 映射类型 [K in keyof T] 遍历对象键生成新类型
  • 键名重映射 as 语法转换键名格式
  • 条件与映射组合可实现属性过滤/类型替换/深度合并
  • infer 关键字在条件类型中推断并提取类型

📝 发现内容有误?点击此处直接编辑

← 上一篇 TypeScript 嵌套递归工具封装
下一篇 → TypeScript 类型兼容深层逻辑
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库