社区编辑申请
注册/登录
TS 类型体操:索引类型的映射再映射
开发 项目管理
TypeScript 给 JavaScript 加了套静态类型系统。其中,JavaScript 中的数组、对象等聚合多个元素的类型在 TypeScript 中对应的是索引类型。

TypeScript 给 JavaScript 加了套静态类型系统。其中,JavaScript 中的数组、对象等聚合多个元素的类型在 TypeScript 中对应的是索引类型。

比如这就是一个索引类型:

type obj = {
name: string;
age: number;
gender: boolean;
}

索引类型可以添加修饰符 readonly(只读)、?(可选):

type obj = {
readonly name: string;
age?: number;
gender: boolean;
}

我们知道,TypeScript 支持类型编程,也就是对类型参数(范型)做各种运算,产生新的类型:

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

那么对于索引类型,如何做运算并产生新的类型呢?

答案是映射类型。

映射类型

映射类型就是用于构造新的索引类型的。

比如这个 Record 类型:

type Record<
K extends string | number | symbol,
T> =
{ [P in K]: T; }

Record 类型构造了一个 key 为 stirng 或 number 或 symbol,而 value 为类型 T 的索引类型。它是 TS 内置的高级类型。

在构造新的索引类型的过程中,还可以做加上一些修饰符。

比如 ReadOnly:

type Readonly<T> =  {
readonly [Key in keyof T]: T[Key];
}

它创建了一个新的索引类型,在原来索引类型的每个属性上加上了 readonly 的修饰:

比如 Partial:

type Partial<T> = {
[Key in keyof T]?: T[Key]
}

它创建了一个新的索引类型,在原来索引类型的每个属性上加上了 ? 的修饰:

可以加上,当然也可以去掉:

去掉可选(?):

type Required<T> = {
[Key in keyof T]-?: T[Key]
}

去掉 readonly:

type NotReadOnly<T> = {
-readonly [Key in keyof T]: T[Key]
}

过完这些例子,映射类型能干什么就比较清楚了:

映射类型可以生成新的索引类型,在生成过程中可以加上或去掉 readonly、? 的修饰符。内置的 Record、ReadOnly、Required、Partial 等类型都是映射类型。

但是,现在的映射类型还是有局限性的,不能对索引名做修改、过滤等操作,功能还不够强。

如果想实现过滤、转换,那就得用到映射类型的重映射了。

重映射

重映射就是在索引后加一个 as 语句,表明索引转换成什么,它可以用来对索引类型做过滤和转换。

比如过滤出类型为 string 的索引:

type FilterString<T> = {
[Key in keyof T as T[Key] extends string ? Key: never]: T[Key];
}

返回 never 代表过滤掉,否则保留。

还可以对索引做转换,比如修改索引名,加上 get:

type Getters<T extends Record<any, any>> = {
[Key in keyof T as `get${Capitalize<Key & string>}`]: T[Key];
}

T extends xxx 是给类型参数的约束,表示只能传入这种类型。这里的 Record 类型是生成索引类型的,我们上面介绍过,所以 T extends Record 就是约束了这里只能传入索引类型。

as 后面是把索引转换成什么,我们是在原来的基础上做了修改,加上了 get,并且后面内容首字母大写,这个 Capitalize 也是 TS 内置的类型。

效果如下:

这两个例子分别说明了重映射 as 可以用来做索引类型的过滤和转换,可以对索引类型做更灵活的编程。

比如,实现 key 和 value 的互换:

type Flip<T extends Record<any, any>> = {
[Key in keyof T as `${T[Key]}`]: Key
}

支持重映射之后,映射类型可以对索引类型做更多的修改。

总结

TypeScript 通过索引类型来表示有多个元素的聚合类型,比如数组、对象等。

TS 支持类型编程,也就是对类型参数做各种运算然后返回新的类型。对索引类型当然也可以做运算,对应的类型就是映射类型。

映射类型在生成新的索引类型的过程中,还可以加上或去掉 readonly、?的修饰符。内置的 Record、Required、Partial、ReadOnly 都是映射类型。

如果想对索引类型做进一步的过滤和转换,就需要用到 as 的重映射,它可以对索引做修改(当索引为 never 就代表过滤掉该索引)。

会用索引类型是只是基础,会用映射类型和重映射就是进阶内容了,这部分可以写出很多复杂的类型逻辑,属于类型体操的范畴。


责任编辑:武晓燕 来源: 神光的编程秘籍
相关推荐

2022-04-08 14:47:11

ArkUI列表字母索引鸿蒙

2022-05-06 09:21:21

TypeScriptinterfacetype

2022-04-07 07:51:40

代码结构设计

2022-02-23 20:20:48

Kubernetes网络模型

2022-04-13 11:24:18

ETS开发HarmonyOS鸿蒙

2022-04-26 10:11:16

开发工具JavaScript

2022-04-24 14:56:53

容器组件StackTS

2022-03-29 07:33:21

2022-04-13 10:46:26

数字孪生全球经济复苏

2022-03-18 15:55:15

鸿蒙操作系统架构

2022-03-07 11:15:25

Pinia状态库vue3

2022-03-09 14:45:09

新加坡数字孪生数据

2022-03-19 12:16:49

Redis高并发系统集群部署

2022-03-16 14:05:04

区块链人工智能物联网

2022-03-10 11:04:04

Vue3Canvas前端

2022-03-07 10:26:25

开源springboot项目

2022-04-29 06:54:48

TS 映射类型User 类型

2022-01-07 09:56:16

2022-04-18 10:20:31

数据映射工具

2022-02-12 22:16:53

同话题下的热门内容

2022 了,你还不知道 Multi-repo 和 Mono-repo 的区别么?我们一起聊聊 API 安全玩转 Image 篇,推荐十个你没见过的图片处理神器项目,YYDS!

编辑推荐

从人肉运维到智能运维,京东金融服务监控的进阶之路阿里10年分布式数据库技术沉淀,AliSQL X-Cluster的应用实战爱奇艺CTO汤兴:道天地将法,《孙子兵法》的管理之道强一致、高可用、自动容灾能力背后,阿里X-Paxos的应用实践猫眼电影李明辉:机器学习在票房预估中的实战
我收藏的内容
点赞
收藏

51CTO技术栈公众号