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

TypeScript 映射类型与条件类型

映射类型与条件类型是 TypeScript 高阶类型体系的核心,下面梳理用法与原理。

映射类型

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

TypeScript
type Options = {
  [K in "host" | "port" | "timeout"]: string;
};
// 等价于:{ host: string; port: string; timeout: string; }

基于现有类型映射

TypeScript
interface User {
  name: string;
  age: number;
  email: string;
}

type UserOptions = {
  [K in keyof User]: User[K];
};
// 等价于 User

修饰符

TypeScript
// 添加可选
type Partial<T> = {
  [K in keyof T]?: T[K];
};

// 添加只读
type Readonly<T> = {
  readonly [K in keyof T]: T[K];
};

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

// 移除只读(-readonly)
type Mutable<T> = {
  -readonly [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 ExcludeMethods<T> = {
  [K in keyof T as T[K] extends Function ? never : K]: T[K];
};

class User {
  id: string = "";
  getName() { return "Alice"; }
}

type DataOnly = ExcludeMethods<User>;
// { id: string }

条件类型

语法 T extends U ? X : Y

TypeScript
type IsString<T> = T extends string ? true : false;

type A = IsString<string>;   // true
type B = IsString<number>;   // false

infer 类型推断

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; }

条件类型链

TypeScript
type Flatten<T> = T extends string[]
  ? T[number]
  : T extends infer U[]
    ? U
    : T;

type A = Flatten<string[]>;    // string
type B = Flatten<number[]>;    // number
type C = Flatten<boolean>;     // boolean

分布式条件类型

联合类型传入条件类型时自动分发处理:

TypeScript
type ToArray<T> = T extends any ? T[] : never;

type A = ToArray<string | number>;
// 分发为:ToArray<string> | ToArray<number>
// 结果:string[] | number[]

阻止分发

用元组包裹类型参数:

TypeScript
type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;

type B = ToArrayNonDist<string | number>;
// [string | number] extends [any] 不触发分发
// 结果:(string | number)[]

分布式排除

TypeScript
type RemoveNull<T> = T extends null ? never : T;

type A = RemoveNull<string | number | null>;
// 分发为:RemoveNull<string> | RemoveNull<number> | RemoveNull<null>
// 结果:string | number

NonNullable 内置实现

TypeScript
// TypeScript 内置
type NonNullable<T> = T extends null | undefined ? never : T;

type A = NonNullable<string | null | undefined>;
// string

要点总结

  • 映射类型 [K in keyof T] 遍历对象键生成新类型
  • 修饰符 ?/readonly 添加可选/只读,-?/-readonly 移除
  • 键名重映射 as 语法转换键名格式
  • 条件类型 T extends U ? X : Y 实现类型分支
  • infer 在条件类型中推断并提取类型
  • 联合类型传入条件类型时自动分发,用元组 [T] 阻止分发

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

← 上一篇 TypeScript 深度类型编程
下一篇 → TypeScript 模板字面量类型与类型提取
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

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

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