文章目录

TypeScript 映射类型:{ [K in keyof T]: T[K] }

发布于 2026-04-09 06:23:14 · 浏览 3 次 · 评论 0 条

TypeScript 映射类型:{ [K in keyof T]: T[K] }

映射类型是 TypeScript 中一种基于旧类型创建新类型的方式。这就像是针对类型的 JavaScript Array.map() 方法:它遍历一个类型的所有属性,对其应用规则,并返回一个新的类型。


核心语法解析

理解 { [K in keyof T]: T[K] } 需要将其拆解为三个逻辑部分:

  1. K in keyof T:这类似于 for (const K in T) 的循环。keyof T 获取类型 T 的所有键名集合,K 则代表其中的每一个键。
  2. [K]:这是新类型的属性名,默认情况下它直接使用了 T 的键名。
  3. T[K]:这是索引访问类型,表示获取 T 中键 K 对应的值类型。

步骤 1:创建基础映射类型

最基础的用法是创建一个结构与原类型完全相同的新类型。

  1. 定义 一个源接口 User
interface User {
  id: number;
  name: string;
  email: string;
}
  1. 编写 映射类型 UserClone
type UserClone = {
  [K in keyof User]: User[K];
};
  1. 验证 类型结果。此时 UserClone 拥有与 User 完全相同的 idnameemail 属性,且类型保持一致。

步骤 2:添加属性修饰符

映射类型的真正威力在于遍历过程中添加修饰符,例如 readonly(只读)或 ?(可选)。

将所有属性设为只读

  1. 添加 readonly 关键字到属性名前:
type ReadonlyUser = {
  readonly [K in keyof User]: User[K];
};
  1. 尝试 修改 属性。如果声明一个变量为 ReadonlyUser 类型,TypeScript 将阻止你对其任何属性重新赋值。

将所有属性设为可选

  1. 添加 问号 ? 到属性名后:
type PartialUser = {
  [K in keyof User]?: User[K];
};
  1. 赋值 空对象。对于 PartialUser 类型的变量,const u: PartialUser = {} 是合法的,因为所有属性都变成了可选的。

步骤 3:键重映射

使用 as 关键字可以重写键的名称。这在生成 Getters/Setters 或添加前缀时非常有用。

  1. 构建 一个为所有属性添加 get 前缀的类型:
  • 使用 Capitalize 工具类型将首字母大写。
  • 使用模板字面量类型拼接字符串。
type Getters = {
  [K in keyof T as `get${Capitalize<K & string>}`]: () => T[K];
};
  1. 应用 该类型到 User
type UserGetters = Getters<User>;
  1. 检查 结果类型结构。UserGetters 现在包含以下方法:
  • getId: () => number
  • getName: () => string
  • getEmail: () => string

步骤 4:值类型转换

通过修改 T[K] 部分,可以将属性值类型强制转换为另一种类型。

  1. 创建 将所有属性转换为 Promise 的包装类型:
type Asyncify = {
  [K in keyof T]: Promise;
};
  1. 观察 变化。Asyncify<User>name 属性类型从 string 变成了 Promise<string>

步骤 5:实战构建“表单模型”类型

在开发中,后端返回的数据模型可能与前端表单输入组件(通常全是字符串)不一致。我们可以用映射类型自动生成表单类型。

  1. 定义 后端数据模型 ProductModel
interface ProductModel {
  id: number;
  price: number;
  isAvailable: boolean;
  tags: string[];
}
  1. 编写 强制所有属性为字符串的映射类型:
type FormModel = {
  [K in keyof T]: string;
};
  1. 生成 前端表单所需的类型:
type ProductForm = FormModel<ProductModel>;
  1. 对比 原始类型与表单类型的差异:
键名 原始类型 表单类型 说明
id number string 表单输入框通常是字符串
price number string 提交时需转换回数字
isAvailable boolean string 复选框值通常为 "on"/"off"
tags string[] string 表单可能是逗号分隔的字符串
  1. 使用 ProductForm 定义组件 Props。这样可以确保组件接收到的全是字符串类型,而底层数据结构依然由 ProductModel 维持。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文