这些是 TypeScript 的类型级别编程工具 — 它们从现有类型计算新类型。
映射类型 — 转换每个属性
映射类型对类型的键进行迭代并转换每一个:
ts
<T> = { [K keyof T]: T[K] };
<T> = { [K keyof T]?: T[K] };
{ : ; : ; }
= <>;
这些是 TypeScript 的类型级别编程工具 — 它们从现有类型计算新类型。
映射类型对类型的键进行迭代并转换每一个:
<T> = { [K keyof T]: T[K] };
<T> = { [K keyof T]?: T[K] };
{ : ; : ; }
= <>;
[K in keyof T] 循环每个键 K;T[K] 是该键的值类型。这是 Partial、Readonly 和 Required 的实现方式。你也可以重新映射键并添加修饰符(-readonly、-? 移除它们)。
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"
T extends U ? X : Y 是类型级别的 if/else。使用 infer 你可以在条件内提取类型:
type ElementOf<T> = T extends (infer U)[] ? U : never;
type E = ElementOf<string[]>; // string
// Make only the function-valued properties optional
type PartialMethods<T> = {
[K in keyof T]: T[K] extends Function ? T[K] | undefined : T[K];
};
映射类型也在条件中分布在 unions 上,启用强大的转换。
映射和条件类型让库能够表达精确的类型关系 — 它们实现了工具类型,为表单/验证库、ORM 查询构建器和推断响应形状的 API 客户端提供支持。
它们很高级,但理解它们解释了 TypeScript 的类型系统如何能够如此表达力强,并让你构建可重用的类型转换,而不是手工编写变体。