本篇先从类型操作(keyof)说起,然后主要说的是TypeScript进阶的接口和类。提示:图片代码里的注释可以认真看一下哟!
前言
『前期回顾』
类型操作(keyof)
keyof (引类型查询操作符)
-
是在TS2.1引入的。
-
它获取类型上所有已知、public的键对应的类型联合
-
number,string,symbol(TS4.4之后开始支持)三种类型可以作为key
-
number[]等同于
Array<number>
(这个要记住)
简单类型的keyof
type K1 = keyof unknown; // never
type K3 = keyof undefined; // never
type K4 = keyof void; // never
type K5 = keyof null; // never
type K11 = keyof object; // never
type K12 = keyof never; // never
type K2 = keyof any; // string | number | symbol
key来自对应的interface :
Number, BigInt, Boolean, String, Symbol
接口( Interface )
什么是接口?
接口(Interfaces)是对行为的抽象,具体如何行动需要由类(classes)去实现(implement)。除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。
示例1:
- 定义一个接口IPerson
- 定义一个变量customer,它的类型是IPerson
- customer实现接口 IPerson 的属性和方法
(左边TS,右边编译后的JS)
示例2:
-
现在我们再定义一个变量visitor
-
这次变量少了一个属性lastName
-
可以看到TS给我们提示了错误
【说明定义的变量比接口的属性少是不允许的】
示例3:
-
又定义了一个变量traveler
-
这次变量多加了一个属性name
-
可以看到TS也给我们提示了错误
【说明定义的变量比接口的属性多也是不允许的】
知识点
- 接口一般首字母大写。有的编程语言中会建议接口的名称加上
I
前缀 - 接口起到一种限制和规范的作用
- 赋值的时候,变量的形状必须和接口的形状保持一致
可选属性
上面的示例中,我们看到,定义的变量是不能比接口的属性少的,如果想少怎么办?
可以用【可选属性】,就是在属性名后面加一个?
号
任意属性
我们现在实现了属性可以比接口少,但是如果【定义的变量想比接口的属性多】怎么办?
我们可以使用【任意属性】来实现,任意属性有两种定义的方式(指的是属性名)
- 一种属性(索引)签名是
string
类型 - 一种属性(索引)签名是
number
类型
[propNum: string]: string
[propNum: number]: string
注:
- 一旦定义了任意属性,那么其他属性(确定属性、可选属性、只读属性等)的类型都必须是它的类型的子集
理解示例
可以改成这样(联合类型)
[propNum: string]: string | number;
有一个特殊的情况:number
类型的任意属性签名不会影响其他 string
类型的属性签名
- 两种任意类型签名并存时,【
number
类型的签名】指定的值类型必须是 【string
类型的签名】指定的值类型的子集
理解示例
因为 Function
是 object
的子集,所以定义不报错
【
number
类型的签名】指定的值类型必须是 【string
类型的签名】指定的值类型的子集。
这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。 也就是说用 100(一个number)去索引等同于使用"100"(一个string)去索引
接口和类型别名
接口( Interface )与类型别名(Type aliases)可以认为是同一概念的两种语法
类比:
函数定义与函数表达式
对比:
定义相同类型时,接口与类型别名的写法
区别
接口( Interface )与类型别名(Type aliases)的区别?
- 类型别名更为通用,其右侧可以包含类型表达式(类型联合、类型交叉、条件类型),但接口右侧只能是某种结构( {...} )
- 接口间继承( extends )时TS会检查二者关系。但类型联合时TS会尽最大努力尝试, 不会报错
- 同一个作用域中的多个同名接口声明会被合并。而多个同名类型别名会报错
类(class)
class是ES2015引|入的新特性,这里只讲如何用interface描述一个class?
class本质上还是一个函数
- 作为构造器的函数,必须具有prototype属性。 并且prototype类型和构造器返回值的类型相同
- 和Point constructor具有相同的函数签名和返回值
定义构造器的语法: new(x: X, y: Y, ...): ReturnType
重要
需要明确,在描述一个class时,我们不是在描述一个对象,而是一个函数,这个函数上有一个prototype属性
结语
本节课的讲师:字节前端—王韦华
如以上有错误的地方,请在评论区中指出!
如果有收获的话,就留个赞鼓励一下吧!😘