TS进阶之keyof
刷完了type-challenges的所有简单和中等难度的题目后,对TypeScript的类型操作有了一些新的理解和认识。特此用几篇文章来记录下一些重要的知识点。
本系列文章需要您对TypeScript有基本的了解
基本用法
JavaScript通过 Object.keys()
获取对象的所有属性键值,而typescript主要关注的是类型操作,通过 keyof
操作符可以获取对象中的所有键类型组成的联合类型。
为了具体了解keyof
操作符的作用,我们通过一些例子来解释下:
type Person = {id: number;name: string;age: number;
};type P1 = keyof Person; //'id' | 'name' | 'age'
keyof
操作符得到的是Person
类型的所有键值类型即'id'
,'name'
和'age'
三个字面量类型组成的联合类型'id' | 'name' | 'age'
。
实际应用
接下来我会用一些例子讲解keyof
的应用。
获取对象所有属性的类型
type P2 = Person[keyof Person]; // number | string
Person['key']
是查询类型(Lookup Types), 可以获取到对应属性类型的类型;Person[keyof Person]
本质上是执行Person['id' | 'name' | 'age']
;- 由于联合类型具有分布式的特性,
Person['id' | 'name' | 'age']
变成了Person['id'] | Person['name'] | Person['age']
;- 最后得到的结果就是
number | string
.
约束范型参数的范围
type MyPick<T, K extends keyof T> = { [P in K]: T[P] };
type P3 = MyPick<Person, 'id' | 'age'>
K extends keyof T
对K
进行了约束,只能是'id','name','age'
中的一个类型或者几个类型组成的联合类型;- 如果没有这个约束,
{ [P in K]: T[P] }
则会报错。
和映射类型组合实现某些功能
- 给对象类型的所有属性加上
readonly
修饰符
type MyReadonly<T> = { readonly [P in keyof T]: T[P] };
type P4 = MyReadonly<Person>; // { readonly id: number; readonly name: string; readonly age: number; }
[P in keyof T]
是对所有属性的键值类型进行遍历,案例中得到的P
分别是'id'
,'name'
和'age'
;T[P]
是查询类型,上面介绍过了,Person['id']
的结果是number
,Person['name']
的结果是string
,Person['age']
的结果是number
。- 将每个属性类型添加
readonly
修饰符,最后的结果就是{ readonly id: number; readonly name: string; readonly age: number; }
- 去掉对象类型的某些属性
微软官是通过Pick
和exclude
组合来实现Omit
逻辑的,我们可以通过以下的代码实现同样的功能。
type MyOmit<T, K> = { [P in keyof T as P extends K ? never : P]: T[P] };
type P5 = MyOmit<Person, 'id' | 'name'> // {age: number;}
代码中的
as P extends K ? never : P
这部分代码叫做重映射 ,因为我们不一定需要的是P
,有些情况下需要对P
进行一些转换;案例中K
中包含的P
键值类型则通过never
忽略了,相反则保留。所以最后的结果是{age: number;}
- 给对象类型添加新的属性
type AppendToObject<T, U extends keyof any, V> = {[P in keyof T | U]: P extends keyof T ? T[P] : V}
type P6 = AppendToObject<Person, 'address', string> // { address: string; id: number; name: string; age: number; }
和条件类型组合实现功能
- 两个对象类型合并成一个新的类型
type Merge<F extends Record<string, any>, S extends Record<string, any>> = {[P in keyof F | keyof S]: P extends keyof S ? S[P] : P extends keyof F ? F[P] : never;
};type Skill = {run: () => void;
}type P7 = Merge<Person, Skill>; // { id: number; name: string; age: number; run: () => void; }
案例中
P extends keyof S ? X : Y
的部分叫做条件类型
(后面也会单独介绍)。代码中的含义就是如果P
是F
的属性类型,则取F[P]
,如果P
是S
的属性类型,则取S[P]
。
小结
经过前面的介绍,应该对keyof
的使用有一些感觉了。下面我列一些代码,大家可以感受下:
type _DeepPartial<T> = { [K in keyof T]?: _DeepPartial<T[K]> }
type Diff<T extends Record<string, any>, U extends Record<string, any>> = {[P in keyof U | keyof T as P extends keyof U? P extends keyof T? never: P: P extends keyof T? P: never]: P extends keyof U ? U[P] : P extends keyof T ? T[P] : never;
};
这个实现逻辑涉及到了其他的知识点有点复杂,没完全看懂没关系,后面会介绍。
TS进阶之keyof相关推荐
- 【TypeScript】TS进阶-函数重载(七)
- 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!
前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 本文知识图谱分基础.进阶和实战三个部分,分别如下: image.png image.png image.png 这三份知识图谱里罗列的 ...
- 「1.8W字」2020不可多得的 TS 学习指南
阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从 ...
- 写给初中级前端的高级进阶指南(万字长文,建议收藏)
前言 由于公众号文章不允许外链,需要跳转文中链接的同学可以在脚注里找到各个的资源链接,也可以通过点击阅读原文更加方便的跳转链接. 我曾经一度很迷茫,在学了 Vue.React 的实战开发和应用以后,好 ...
- 写给初中级前端的高级进阶指南(万字路线)
前言 我曾经一度很迷茫,在学了 Vue.React 的实战开发和应用以后,好像遇到了一些瓶颈,不知道该怎样继续深入下去.相信这也是很多一两年经验的前端工程师所遇到共同问题,这篇文章,笔者结合自己的一些 ...
- th:text为null报错_为vue3.0的学习TS解读高级类型
知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...
- as button onitemclicklistener为null_为vue3.0的学习TS解读高级类型
知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...
- typescript ajax,TypeScript的应用方式
> 本文不讲如何安装,只讲代码中的实际应用 # 一.什么是 TypeScript? typescript是js的超集,它在js的基础上增加了静态类型校验,可以在运行前校验js中的一些错误并修正. ...
- 入门前端学习路线图【送书】
大家好,我是若川.记得点上方音频听小姐姐配音,超级好听. 华章图书又赞助了书籍送福利给大家.本次送4本书的抽奖方式是:截止到9月6日(周一)20:00,在留言区留言任意内容.我会在留言区抽取「1位」关 ...
最新文章
- VTK:Qt之BarChartQt
- 如何调试 web worker
- android sdk 目录说明,Android的sdk、api及工程目录说明
- 信息学奥赛一本通(1087:级数求和)
- centos7下的elasticsearch-6.2.4安装
- 神经网络有趣案例_求解三体问题快了1亿倍,新型神经网络问世
- 大企业中,Java面试官最爱问的问题集锦
- mysql 触发器和存储过程组合使用,实现定时触发操作
- 数据库sql语句杂谈
- DIY一个VR小钢炮
- 三菱伺服调试软件_【精品】三菱MR-J4系列伺服驱动器一键自整定操作流程
- 2008年国外最漂亮的50个网站欣赏
- python做excel表格代码_Python读写Excel表格
- 在网页中如何设置背景图片
- 转载—左耳朵耗子《程序员如何把控自己的职业》
- orangepi——uart串口开发(TX,RX)
- easybuy项目总结
- 七夕情人节朋友圈要红包说说推荐
- 系统的三高,分别是哪三高?
- 【04Vue3 目录结构】VUE3目录结构概述结构详解目录结构的作用注意事项