知识点摘要

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

自动类型推断(不用你标类型了,ts自己猜)

大家现在写ts的时候一定会在每个变量后面都加上类型吧? 但是?

现在告诉大家有些情况下你不需要标注类型, ts可以根据你写的代码来自动推断出类型:

赋值字面量给变量
let n = 1; // ts会自动推断出n是number类型n+=3 // 不报错,因为已知类型

let arr1 = []; // 类型为: any[]arr1.push(1,2,{o:3}); 

let arr = [1]; // 内部要有数字, 才能推断出正确类型arr.push(2);

自动阅读if条件判断
let n: number|null = 0.5 < Math.random() ? 1:null;if(null !== n){    n+=3 // ts知道现在n不是null是number}
浏览器自带api
document.ontouchstart = ev=>{ // 能自动推断出ev为TouchEventconsole.log(ev.touches);  // 不报错, TouchEvent上有touches属性}
typeof

typeof就是js中的typeof, ts会根据你代码中出现的typeof来自动推断类型:

let n:number|string = 0.5 < Math.random()? 1:'1';

// 如果没有typeof, n*=2会报错, 提示没法推断出当前是number类型, 不能进行乘法运算if('number' === typeof n) {    n*= 2;} else  {    n= '2';}

注意: 在ts文档中, 该部分的知识点叫做typeof类型保护, 和其他类型推断的内容是分开的, 被写在高级类型/类型保护章节中.

instanceof

ts会根据你代码中出现的instanceof来自动推断类型:

let obj = 0.5 < Math.random() ? new String(1) : new Array(1);if(obj instanceof String){// obj推断为String类型    obj+= '123'} else {// obj为any[]类型    obj.push(123);}

注意: 在ts文档中, 该部分的知识点叫做instanceof类型保护, 和其他类型推断的内容是分开的, 被写在高级类型/类型保护章节中.

类型断言(你告诉ts是什么类型, 他都信)

有些情况下系统没办法自动推断出正确的类型, 就需要我们标记下, 断言有2种语法, 一种是通过"<>", 一种通过"as", 举例说明:

let obj = 0.5 < Math.random() ? 1 : [1]; // number|number[]

// 断言, 告诉ts, obj为数组(<number[]>obj).push(1);

//等价(obj as number[]).push(1);

类型别名(type)

类型别名可以表示很多接口表示不了的类型, 比如字面量类型(常用来校验取值范围):

type A = 'top'|'right'|'bottom'|'left'; // 表示值可能是其中的任意一个type B = 1|2|3;type C = '红'|'绿'|'黄';type D = 150;

let a:A = 'none'; // 错误, A类型中没有'none'
更多组合:
interface A1{    a:number;}type B = A1 | {b:string};type C = A1 & {b:string};

// 与泛型组合type D<T> = A1 | T[];

索引类型(keyof)

js中的Object.keys大家肯定都用过, 获取对象的键值, ts中的keyof和他类似, 可以用来获取对象类型的键值:

type A = keyof {a:1,b:'123'} // 'a'|'b'type B = keyof [1,2] // '1'|'2'|'push'... , 获取到内容的同时, 还得到了Array原型上的方法和属性(实战中暂时没遇到这种需求, 了解即可)

可以获得键值, 也可以获取对象类型的值的类型:

type C = A['a'] // 等于type C = 1;let c:C = 2 // 错误, 值只能是1

映射类型(Readonly, Pick, Record等...)

映射类型比较像修改类型的工具函数, 比如Readonly可以把每个属性都变成只读:

type A  = {a:number, b:string}type A1 = Readonly<A> // {readonly a: number;readonly b: string;}

打开node_modules/typescript/lib文件夹可以找到lib.es5.d.ts, 在这我们能找到Readonly的定义:

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

其实不是很复杂, 看了本节课前面前面的内容, 这个很好理解是吧:

  1. 定义一个支持泛型的类型别名, 传入类型参数T.

  2. 通过keyof获取T上的键值集合.

  3. in表示循环keyof获取的键值.

  4. 添加readonly标记.

Partial, 让属性都变成可选的
type A  = {a:number, b:string}type A1 = Partial<A> // { a?: number; b?: string;}
Required, 让属性都变成必选
type A  = {a?:number, b?:string}type A1 = Required<A> // { a: number; b: string;}
Pick, 只保留自己选择的属性, U代表属性集合
type A  = {a:number, b:string}type A1 = Pick<A, 'a'> //  {a:number}
Omit 实现排除已选的属性
type A  = {a:number, b:string}type A1 = Omit<A, 'a'> // {b:string}
Record, 创建一个类型,T代表键值的类型, U代表值的类型
type A1 = Record<string, string> // 等价{[k:string]:string}
Exclude, 过滤T中和U相同(或兼容)的类型
type A  = {a:number, b:string}type A1 = Exclude<number|string, string|number[]> // number

// 兼容type A2 = Exclude<number|string, any|number[]> // never , 因为any兼容number, 所以number被过滤掉
Extract, 提取T中和U相同(或兼容)的类型
type A  = {a:number, b:string}type A1 = Extract<number|string, string|number[]> // string
NonNullable, 剔除T中的undefined和null
type A1 = NonNullable<number|string|null|undefined> // number|string
ReturnType, 获取T的返回值的类型
type A1= ReturnType<()=>number> // number
InstanceType, 返回T的实例类型

ts中类有2种类型, 静态部分的类型和实例的类型, 所以T如果是构造函数类型, 那么InstanceType可以返回他的实例类型:

interface A{    a:HTMLElement;}

interface AConstructor{new():A;}

function create (AClass:AConstructor):InstanceType<AConstructor>{return new AClass();}
Parameters 获取函数参数类型

返回类型为元祖, 元素顺序同参数顺序.

interface A{(a:number, b:string):string[];}

type A1 = Parameters<A> // [number, string]
ConstructorParameters 获取构造函数的参数类型

Parameters类似, 只是T这里是构造函数类型.

interface AConstructor{new(a:number):string[];}

type A1 = ConstructorParameters<AConstructor> // [number]

extends(条件类型)

T extends U ? X : Y

用来表示类型是不确定的, 如果U的类型可以表示T, 那么返回X, 否则Y. 举几个例子:

type A =  string extends '123' ? string :'123' // '123'type B =  '123' extends string ? string :123 // string

明显string的范围更大, '123'可以被string表示, 反之不可.

infer(类型推断)

单词本身的意思是"推断", 实际表示在extends条件语句中声明待推断的类型变量. 我们上面介绍的映射类型中就有很多都是ts在lib.d.ts中实现的, 比如Parameters:

type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;

上面声明一个P用来表示...args可能的类型, 如果(...args: infer P)可以表示 T, 那么返回...args对应的类型, 也就是函数的参数类型, 反之返回never.

注意: 开始的T extends (...args: any) => any用来校验输入的T是否是函数, 如果不是ts会报错, 如果直接替换成T不会有报错, 会一直返回never.

应用infer

接下来我们利用infer来实现"删除元祖类型中第一个元素", 这常用于简化函数参数

export type Tail<Tuple extends any[]> = ((...args: Tuple) => void) extends ((a: any, ...args: infer T) => void) ? T : never

---END---

选择”Vue社区 “星标?,内容一触即达。点击原文更多惊喜!

开发者技术前线 汇集技术前线快讯和关注行业趋势,大厂干货,是开发者经历和成长的优秀指南。

历史推荐

7个有用的Vue开发技巧

JavaScript八张思维导图

JavaScript 之实现一个简单的 Vue

听说有人不敢点这里 ?

as button onitemclicklistener为null_为vue3.0的学习TS解读高级类型相关推荐

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

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

  2. (六)Vue3.0预学习

    Vue3.0预学习 Vue3要来了Vue2就要过时了吗 Vue3 Vue2.x马上就要过时了吗 Vue3升级内容 Proxy实现响应式 Object.defineProperty的缺点 Proxy实现 ...

  3. vue3.0 先遣学习

    vue3.0 中文预览地址 vue3.0 github地址 怎么使用vue-cli生成vue3.0的项目? 安装vue-cli v4.5以上版本 npm install -g @vue/cli vue ...

  4. vue3.0需要学习的技术栈

    相关库名称在线地址

  5. vue3.0 php,使用Vue3.0收获的知识点(一)

    前端发展百花放,一技未熟百技出. 茫然不知何下手,关注小编胜百书. 近期工作感觉很忙,都没有多少时间去写文章,今天这篇文章主要是将自己前期学习Vue3.0时候整理的一些笔记内容进行了汇总,通过对本文的 ...

  6. 如何搭建一个完整的Vue3.0 + ts 的项目

    如何搭建一个完整的Vue3.0 + ts 的项目 相信9月18日尤大大的关于Vue3.0的发表演讲大家一定有所关注,现在Vue3.0 也已经进入RC阶段(最终产品的候选版本,如果没有问题则可发布成为正 ...

  7. vue3.0中props父子传值的改动

    前言: 对vue3.0的学习以及对技术更新升级内容的整理与使用,这里分析下他的props父子传值的改动. vue官方入口 目录 一.vue2.0中props的用法 1.父组件中 a.vue中 2.子组 ...

  8. 体验Vue3.0, 仿一个网易云音乐客户端

    一.用到的技术栈 前端: vue3.0全家桶:(ts+jsx) vuex: vuex-module-decorators swiper:非常受欢迎与实用的轮播图插件,swiper create-key ...

  9. SDU信息门户(10)前端vue3.0代码分析

    2021SC@SDUSC 目录 一.引言 二.代码分析 1.答辩检查组件 2.文件系统组件 3.公告组件 4.教师发布题目组件 三.总结 一.引言 SDU信息门户中前端主要使用了Vue3.0的技术,这 ...

最新文章

  1. 用shell解决ddos攻击实例
  2. app让个别界面横屏,其他的为竖屏,解决如下
  3. 【收藏】gitee:使用k8s部署nacos
  4. P3313-[SDOI2014]旅行【树链剖分,线段树】
  5. sql server 群集_SQL Server 2014 –安装群集实例–分步(3/3)
  6. Python3+Dlib+Opencv实现摄像头采集人脸并对表情进行实时分类判读
  7. 三、解线性方程组的迭代法
  8. python批量写入数据库_python实现数据库批量数据插入.
  9. 箫演奏技巧符号大全图解
  10. AI“独角兽”排队上市,但属于AI公司的胜利还没有到
  11. CDGA|数据虚拟化助力数据治理成效显著
  12. Python爬虫-bug处理办法(持续更新)
  13. Html手机web背景全屏,使用全屏背景的网页设计欣赏 全屏网页背景教程
  14. 青花瓷的小鸟装饰蛋糕
  15. AngularJS的优缺点总结
  16. 英语学习单词篇(14)
  17. 曾国藩:从30岁起,脱胎换骨
  18. 基于canvas制作绚丽的倒计时效果
  19. 化三为你解析气流粉碎机的六大性能特点
  20. eiei歌曲计算机谱,偶像练习生主题曲《eiei》歌曲歌词介绍

热门文章

  1. 手动为linux系统添加新用户——过程详解
  2. 关于2d物理引擎box2d与ape的评论
  3. 用Windows Server 2003配置×××
  4. 2019秋季学习计划
  5. 解读30个提高Web程序执行效率的好经验
  6. Spring boot MultipartResolver
  7. [Office一般性操作] 关闭Outlook重定向
  8. Android 2.3发短信详细流程
  9. 【java】spring-boot源码解析之应用启动
  10. Linux权限管理的认知