一文学会 TypeScript 的 82% 常用知识点(下)

Posted sexintercourse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文学会 TypeScript 的 82% 常用知识点(下)相关的知识,希望对你有一定的参考价值。

一文学会 TypeScript 的 82% 常用知识点(下)

前端专栏 2019-11-23 18:39:08
技术图片
 
 

都已经 9021 年了,TypeScript(以下简称 TS)作为前端工程师不得不学的技能,我们必须掌握。

在上篇「一文学会 TypeScript 的 82% 常用知识点(上)」中,主要介绍了 TS 的基本类型,引用类型、类型断言、接口等基础知识点。本篇对剩下对内容进行讨论,包括:类、函数、泛型。

如果 TS 的基础薄弱,建议先阅读上篇,大概二十分钟即可入门。

五、类

类在上篇有所提及,这里作进一步了解。

类的典型结构

包括属性、方法、构造函数。使用关键字 new 创建类的实例。

技术图片
 
 

5.1 类的继承

使用关键字 extends 定义类的继承。

技术图片
 
 

5.2 类的成员修饰符

5.2.1 public

类的成员修饰符默认是 public,也可以显式声明。

技术图片
 
 

上述代码中,属性 a 和 b 均被声明为公共的。

5.2.2 private

将类的成员声明为私有的,即只有类内部访问。

技术图片
 
 

TS 是结构性类型系统(鸭式辨形),如果两种类型的结构相同,一般情况下,TS 会认为它们是兼容的。

技术图片
 
 

可是,当类的成员带有 private 或 protected 修饰符时,情况却不一样。

技术图片
 
 

上述代码中,虽然看上去它们的结构相同。但是,当一个类的成员中存在 private 或 protected 时,如果需要另一个类与它兼容,则需要两个类的声明来源于同一份声明,例如通过继承。

技术图片
 
 

5.2.3 protected

修饰符 protected 和 private 类似,区别在于使用 protected 修饰的成员,在派生类可以访问。

技术图片
 
 

5.2.4 readonly

修饰符 readonly 将属性设置为只读。

技术图片
 
 

将属性设置为只读,只能在初始化时候定义其值,定义后不能修改。

5.2.5 static

在类类型中,我们区分了类的静态部分和类的实例部分。修饰符 static 将类成员声明为静态成员。

技术图片
 
 

5.2.6 抽象类

我们创建基类时,如果不希望基类能被实例化,可以使用 protected 修饰符。

技术图片
 
 

更普遍的做法是,使用 abstract 修饰符。abstract 能定义抽象类和抽象类中的抽象方法。

技术图片
 
 

5.2.7 getter 和 setter

很多时候,对某个属性读取时,同时需要对其进行处理,例如。

技术图片
 
 

更加简单的办法是,通过 存储器 处理。

getter 和 setter 统称存取器,其实在 ES5 就已经存在,很多朋友没有留意。如果对存取器不熟悉的,也可以通过 TS 来理解。

技术图片
 
 

六、函数

在 TS 中,有几种方式定义函数类型。

6.1 函数签名

利用上文提到的函数签名来定义函数类型。

技术图片
 
 

6.2 完整的函数类型

除了使用函数签名外,还可以直接对函数进行类型描述。

技术图片
 
 

但是,这种方式毫无疑问是太繁琐了,TS 存在类型推断的功能,它能根据等号一侧已存在的函数类型,而推断出另一侧的函数类型,从而简化代码。

6.3 类型推断

函数推断简化代码

技术图片
 
 

6.4 可选参数

在 JS 中,参数都是可选的,如果函数声明了参数,但是实际没有传参,则参数值是 undefined。

技术图片
 
 

默认情况下, TS 要求参数是必须的,函数声明了参数,就应该传进对应的参数。

技术图片
 
 

但确实存在某个参数可能存在,可能不存在的情况。这时候就需要用到可选参数了。

技术图片
 
 

值得注意的是,可选参数必须跟在必须参数之后。

6.5 默认参数

在 ES6 中,可以给参数设定默认值。

技术图片
 
 

而在 TS 中,默认参数的特性也是和 ES6 一致,而默认参数的类型是:默认值和 undefined 的联合类型。

技术图片
 
 

6.6 剩余参数

在 ES6 中,引入了剩余参数,代表由剩余所有参数组成的参数数组。

技术图片
 
 

在 TS 中给剩余参数添加类型,和普通参数接近,区别在于剩余参数肯定是数组类型。

技术图片
 
 

6.7 函数重载

函数根据传入不同的参数而返回不同的数据,这是十分普遍的情况。

技术图片
 
 

如何对这种情况进行类型描述呢?有些朋友可能会想到使用联合类型进行处理。

技术图片
 
 

但是,这样不能很好地描述输入和输出类型的关系。

在上述例子中,参数和返回存在对应关系:参数是 number 类型,则返回 boolean,参数是 boolean 类型,则返回 number,其他则返回 undefined。

此时,我们可以运用函数重载描述这些对应关系:

技术图片
 
 

上述代码中,定义了三个 foo 函数的重载,需要注意两点。

  1. 具体的函数声明不属于重载部分,即 function foo(a: any): any 并不是重载,而是具体的函数声明,所以例子中只有三个函数重载;
  2. 当匹配重载列表时候,是根据定义时候的顺序由上到下匹配的。在例子中,传入参数是 undefined 时,首先尝试匹配 number,然后尝试匹配 boolean,最后尝试匹配 any,匹配成功则使用 any 这个重载定义。

7 泛型

泛型其实并不高深,借助几个已知概念可以帮助理解。

7.1 泛型函数

上文提到,当函数的参数和返回的类型存在联系时,我们使用了函数重载进行类型描述。

假如希望函数的参数和返回的值,它们之间的类型一致。如果使用函数重载,则需要:

技术图片
 
 

这显得十分繁琐。而且,当传入的参数是数组或其他对象时,匹配的是函数重载的 object 部分,返回值的类型也是 object,丢失了原有的结构。

我们期望即使传入复杂的结构对象,也保留它们的类型描述。像上述代码中,传入是 number[] 类型的参数,期望返回的也是 number[] 类型描述,而不是 object 类型描述。

而使用泛型就能解决这个问题。以下借助变量的概念来对泛型进行解释。

变量我们都清楚,当变量被赋值成某值或对象时,该变量就代表着某值或对象。

而在类型系统中,通过引入类型变量,达到和变量相同的效果:当类型变量被赋值成某类型,则类型变量就代表该类型。

技术图片
 
 

上述代码中,在函数名后添加 <T>, 代表在类型系统中声明了类型变量 T。所以,在对参数 a 和返回值进行类型描述时,我们可以使用 T 这个类型变量。

另外,上述代码使用字母 T 代表类型变量,并不是固定的,也可以使用字母 A、a 等合法的变量名。只不过约定俗成,T 代表着 Type(类型),这样其他人阅读代码也一目了然。

既然是变量,我们怎么给这个类型变量传参呢?

技术图片
 
 

可以清晰地看到,在调用函数时,使用尖括号传入具体的类型值。以 foo<number[]>([1, 2, 3) 为例,相当于应用 function<number[]>(a: number[]): number[] 类型校验。这样,在参数和返回值中都保留了明确的数据结构。

上文我们提到类型推断,同样在泛型中也可以应用。

技术图片
 
 

上述代码中,省略了明确的类型传参,但 TS 会根据我们传入的参数的类型,自动确定 T 的类型。

7.2 泛型接口

我们知道,接口是具有函数签名的,形如:

技术图片
 
 

接口中的函数签名也存在泛型的形式:

技术图片
 
 

另外,还可以将泛型参数作为接口的参数:

技术图片
 
 

7.3 泛型类

泛型类和泛型接口类似,声明泛型参数后,在类中就可以使用。

技术图片
 
 

结语

以上就是关于 TS 的关键知识点,熟悉上下两篇文章的内容,即可阅读和使用大部分的 TS 代码。

TS 的学习要点不多,一个周末时间基本能搞明白。

学习 TS 的资料主要是官网,特别是 TS handbook,本文大部分内容也是基于其整理的,希望能给大家带来一些帮助。

 

以上是关于一文学会 TypeScript 的 82% 常用知识点(下)的主要内容,如果未能解决你的问题,请参考以下文章

一文学会 Spring MVC 常用注解

一文学会常用 MySQL 分库分表方案

10分钟学会TypeScript,总结TS的常用特性

一文理解Linux的基本指令(下)(三分钟学会Linux基本指令)

一文学会MapReduce编程

(转)一文学会用 Tensorflow 搭建神经网络