刷完了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
  1. Person['key']查询类型(Lookup Types), 可以获取到对应属性类型的类型;
  2. Person[keyof Person]本质上是执行 Person['id' | 'name' | 'age']
  3. 由于联合类型具有分布式的特性,Person['id' | 'name' | 'age'] 变成了 Person['id'] | Person['name'] | Person['age']
  4. 最后得到的结果就是 number | string.
约束范型参数的范围
type MyPick<T, K extends keyof T> = { [P in K]: T[P] };
type P3 = MyPick<Person, 'id' | 'age'>
  1. K extends keyof TK进行了约束,只能是'id','name','age'中的一个类型或者几个类型组成的联合类型;
  2. 如果没有这个约束,{ [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; }
  1. [P in keyof T]是对所有属性的键值类型进行遍历,案例中得到的P 分别是'id','name''age';
  2. T[P]是查询类型,上面介绍过了,Person['id'] 的结果是numberPerson['name'] 的结果是stringPerson['age'] 的结果是number
  3. 将每个属性类型添加readonly修饰符,最后的结果就是 { readonly id: number; readonly name: string; readonly age: number; }
  • 去掉对象类型的某些属性

微软官是通过Pickexclude组合来实现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 的部分叫做 条件类型(后面也会单独介绍)。代码中的含义就是如果 PF的属性类型,则取F[P],如果PS的属性类型,则取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相关推荐

  1. 【TypeScript】TS进阶-函数重载(七)

  2. 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

    前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 本文知识图谱分基础.进阶和实战三个部分,分别如下: image.png image.png image.png 这三份知识图谱里罗列的 ...

  3. 「1.8W字」2020不可多得的 TS 学习指南

    阿宝哥第一次使用 TypeScript 是在 Angular 2.x 项目中,那时候 TypeScript 还没有进入大众的视野.而现在学习 TypeScript 的小伙伴越来越多了,本文阿宝哥将从 ...

  4. 写给初中级前端的高级进阶指南(万字长文,建议收藏)

    前言 由于公众号文章不允许外链,需要跳转文中链接的同学可以在脚注里找到各个的资源链接,也可以通过点击阅读原文更加方便的跳转链接. 我曾经一度很迷茫,在学了 Vue.React 的实战开发和应用以后,好 ...

  5. 写给初中级前端的高级进阶指南(万字路线)

    前言 我曾经一度很迷茫,在学了 Vue.React 的实战开发和应用以后,好像遇到了一些瓶颈,不知道该怎样继续深入下去.相信这也是很多一两年经验的前端工程师所遇到共同问题,这篇文章,笔者结合自己的一些 ...

  6. th:text为null报错_为vue3.0的学习TS解读高级类型

    知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...

  7. as button onitemclicklistener为null_为vue3.0的学习TS解读高级类型

    知识点摘要 本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer) 自动 ...

  8. typescript ajax,TypeScript的应用方式

    > 本文不讲如何安装,只讲代码中的实际应用 # 一.什么是 TypeScript? typescript是js的超集,它在js的基础上增加了静态类型校验,可以在运行前校验js中的一些错误并修正. ...

  9. 入门前端学习路线图【送书】

    大家好,我是若川.记得点上方音频听小姐姐配音,超级好听. 华章图书又赞助了书籍送福利给大家.本次送4本书的抽奖方式是:截止到9月6日(周一)20:00,在留言区留言任意内容.我会在留言区抽取「1位」关 ...

最新文章

  1. VTK:Qt之BarChartQt
  2. 如何调试 web worker
  3. android sdk 目录说明,Android的sdk、api及工程目录说明
  4. 信息学奥赛一本通(1087:级数求和)
  5. centos7下的elasticsearch-6.2.4安装
  6. 神经网络有趣案例_求解三体问题快了1亿倍,新型神经网络问世
  7. 大企业中,Java面试官最爱问的问题集锦
  8. mysql 触发器和存储过程组合使用,实现定时触发操作
  9. 数据库sql语句杂谈
  10. DIY一个VR小钢炮
  11. 三菱伺服调试软件_【精品】三菱MR-J4系列伺服驱动器一键自整定操作流程
  12. 2008年国外最漂亮的50个网站欣赏
  13. python做excel表格代码_Python读写Excel表格
  14. 在网页中如何设置背景图片
  15. 转载—左耳朵耗子《程序员如何把控自己的职业》
  16. orangepi——uart串口开发(TX,RX)
  17. easybuy项目总结
  18. 七夕情人节朋友圈要红包说说推荐
  19. 系统的三高,分别是哪三高?
  20. 【04Vue3 目录结构】VUE3目录结构概述结构详解目录结构的作用注意事项

热门文章

  1. oppo系统android版本下载,oppo手机助手安卓版
  2. 掐头去尾-利用正则表达式的匹配顺序
  3. C# 阿里云短信接口调用(不使用SDK,单文件完成)
  4. Android音频可视化
  5. HDFS删除并清空回收站
  6. 做第一批35岁就退休的90后,需要几步?
  7. Win10连接远程桌面失败
  8. java调用腾讯地图根据经纬度获取位置信息
  9. Python去除文章首尾空格换行符
  10. 公司规定所有接口都用 POST请求,这是为什么?