TS 类型工具 : Record的使用

20,183 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

TS 给我们提供了一系列的高级类型,简化了我们在类型定义时的工作,其中 Record 又被广泛的使用,这篇文章介绍了 Record 是如何定义的,以及如何理解 Record 的源码,同时给出了 Record 的常见的使用场景。

释义

Record<K,T>

Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type.” —

构造一个对象类型,Keys 表示对象的属性键 、Type 表示对象的属性值,用于将一种类型属性映射到另一种类型

理解为:将 K 的每一个值都定义为 T 类型

源码

/**
 * Construct a type with a set of properties K of type T
 */
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

源码也比较简单,即将K中的每个属性([P in K]),都转为T类型。常用的格式如下:

type proxyKType = Record<K,T>

会将K中的所有属性值都转换为T类型,并将返回的新类型返回给proxyKType,K可以是联合类型、对象、枚举等

示例1

一条数据的状态值有:

  • 已创建 created
  • 已提交 submited
  • 已删除 removed
type state = "created" | "submitted" | "removed"

现在需要创建一个状态值映射对象, 这个兑现的成员是每一个状态值,成员的值是String类型。

如果我们手动描述类型的需要这么写:

interface StatesInterface {
  created:string
  submitted:string
  removed:string
}

export const states:StatesInterface = {
  created:'01',
  submitted:'02',
  removed:'03'
}

使用Record后可以省去我们对StatesInterface接口的定义:

export const states:Record<state,string> = {
  created:'01',
  submitted:'02',
  removed:'03'
}

示例2

比如现在要定义一个叫食物原料的对象,对象的值由我们规定的几种食物原料组成,我们可以定义原料类型,原料类型可以是巧克力,可可,蘑菇等,并且他们都是string类型,然后使用 Record 对他们进行包装。如下:

type Ingredient = "chocolate" | "peanuts" | "cocoa" | "marshmallow" | "cherry";

export const ingredients: Record<Ingredient, string> = {
  chocolate: "Chocolate",
  cocoa: "Cocoa Powder",
  cherry: "Cherry",
  marshmallow: "Marshmallow",
  peanuts: "Peanut Butter",
};

当然也可以自己在第一个参数后追加额外的值,如:

type Ingredient = "chocolate" | "peanuts" | "cocoa" | "marshmallow" | "cherry";

export const ingredients: Record<Ingredient | "apple", string> = {
  chocolate: "Chocolate",
  cocoa: "Cocoa Powder",
  cherry: "Cherry",
  marshmallow: "Marshmallow",
  peanuts: "Peanut Butter",
  apple: "Apple"
};

额外添加了一种原料叫 Apple

使用场景

通过了解 Record 的源码以及相关例子的实现,可以总结出以下常见的Record使用场景:

  • 当我们想限制对象的属性时
  • 转换现有类型的属性并将其值转换为其它类型时(结合keyof使用)

Record是一个有用和简要的工具类型,可以让你的代码更健壮,在编译时更容易捕获错误,并且使IDE更加容易的标记错误。