映射类型

概述

在 TypeScript 中,映射类型(Mapped Types)是一种强大的工具,允许你基于现有类型创建新类型。映射类型通常用于将现有类型的属性转换为其他类型,例如将所有属性变为可选的、只读的,或者将属性类型进行转换。

基本概念

什么是映射类型?

映射类型是一种通过遍历现有类型的属性来创建新类型的方法。你可以对这些属性进行各种操作,如添加修饰符(如 readonly 或 ?),或者将属性类型进行转换。

映射类型的语法

映射类型的基本语法如下:

type MappedType = {
  [P in K]: T
};
  • P 是属性名变量,代表当前遍历的属性。
  • K 是属性名的联合类型,通常是一个字符串字面量类型。
  • T 是属性的新类型。

示例:将所有属性变为可选的

假设我们有一个现有的类型 Person,我们希望创建一个新类型 PartialPerson,其中所有属性都是可选的。

type Person = {
  name: string;
  age: number;
  address: string;
};

type PartialPerson = {
  [P in keyof Person]?: Person[P];
};

// 使用 PartialPerson 类型
const partialPerson: PartialPerson = {
  name: "John",
};

在这个例子中,PartialPerson 类型通过映射 Person 类型的所有属性,并将每个属性变为可选的。

示例:将所有属性变为只读的

同样,我们可以将所有属性变为只读的:

type ReadonlyPerson = {
  readonly [P in keyof Person]: Person[P];
};

// 使用 ReadonlyPerson 类型
const readonlyPerson: ReadonlyPerson = {
  name: "John",
  age: 30,
  address: "123 Main St",
};

// 尝试修改只读属性会报错
// readonlyPerson.name = "Jane"; // Error: Cannot assign to 'name' because it is a read-only property.

实践练习

练习 1:创建一个映射类型,将所有属性变为字符串类型

假设我们有一个类型 User,我们希望创建一个新类型 StringifiedUser,其中所有属性都是字符串类型。

type User = {
  id: number;
  username: string;
  email: string;
  age: number;
};

type StringifiedUser = {
  [P in keyof User]: string;
};

// 使用 StringifiedUser 类型
const stringifiedUser: StringifiedUser = {
  id: "1",
  username: "john_doe",
  email: "[email protected]",
  age: "30",
};

练习 2:创建一个映射类型,将所有属性变为可选的且只读的

假设我们有一个类型 Product,我们希望创建一个新类型 PartialReadonlyProduct,其中所有属性都是可选的且只读的。

type Product = {
  id: number;
  name: string;
  price: number;
  description: string;
};

type PartialReadonlyProduct = {
  readonly [P in keyof Product]?: Product[P];
};

// 使用 PartialReadonlyProduct 类型
const partialReadonlyProduct: PartialReadonlyProduct = {
  id: 1,
  name: "Laptop",
};

// 尝试修改只读属性会报错
// partialReadonlyProduct.name = "Desktop"; // Error: Cannot assign to 'name' because it is a read-only property.

总结

映射类型是 TypeScript 中非常强大的工具,允许你基于现有类型创建新类型,并对属性进行各种操作。通过映射类型,你可以轻松地将属性变为可选的、只读的,或者将属性类型进行转换。掌握映射类型将极大地提升你在 TypeScript 中的类型操作能力。

下一步

在掌握了映射类型的基本概念和使用方法后,你可以继续学习 TypeScript 中的其他高级类型操作,如条件类型、infer 关键字和工具类型(如 Partial、Readonly、Pick 等)。这些工具将进一步增强你在 TypeScript 中的类型操作能力。