TS学习笔记之对象

143 阅读6分钟

该系列文章是本人阅读阮一峰老师的《TypeScript教程》学习笔记,欢迎各位大佬指出不正确的地方,感谢!

简介

除了原始类型,对象是JS最基本的数据结构,TS对于对象类型有很多规则。

对象类型的最简单声明方法,就是使用大括号表示对象,在大括号内部声明每个属性和方法的类型。 image.png

属性的类型可以用分号结尾,也可以用逗号结尾。 image.png

一旦声明了类型,对象赋值时,就不能缺少指定的属性,也不能有多余的属性,读写不存在的属性也会报错,删除类型声明中存在的属性也会报错,但是可以修改它的值。

对象的方法使用函数类型描述。 image.png

对象类型可以使用方括号读取属性的类型。 image.png

除了type命令可以为对象类型声明一个别名,TS还提供了interface命令,可以把对象类型提炼为一个接口。 image.png

注意,TS不区分对象自身的属性和继承的属性,一律视为对象的属性。 image.png

可选属性

如果某个属性是可选的(即可忽略),需要在属性名后面加一个问号。 image.png

可选属性等同于允许赋值为undefined,下面两种方法是等效的。 image.png 所以读取一个可选属性的时候,可能得到undefined,在读取之前必须检查一下是否为undefined。 image.png

只读属性

属性名前面加还是那个readonly关键字,表示这个属性是只读属性,不能修改。 image.png

只读属性只能在对象初始化期间赋值,此后就不能修改该属性。

注意,如果属性值是一个对象,readonly修饰符并不禁止修改该对象的属性,只是禁止完全替换掉该对象。 image.png

如果一个对象有两个引用,即两个变量对应一个对象,其中一个变量是可写的,另一个变量是只读的,那么从可写变量修改属性,会影响到只读变量。 image.png

如果希望属性值是只读的,除了声明时加上readonly关键字,也可以在赋值时在对象后面加上只读断言as const。 image.png as const属于TS的类型推断,如果变量明确地声明了类型,那么TS会以声明的类型为准。 image.png

属性名的索引类型

因为对象的属性非常多,有时候对象属性的数量也无法判断,所以TS允许采用属性名表达式的写法来描述类型,称为“属性名的索引类型”。

索引类型里面最常见的就是属性名的字符串索引。 image.png

JS对象的属性名的类型有三种可能:string、number和symbol。 image.png

对象可以同时有多种类型的属性名索引,比如同时拥有数值索引和字符串索引。但数值索引不能与字符串索引发生冲突,必须服从后者,因为在JS中,所有的数值属性名都会自动转为字符串属性名。 image.png

同样的,可以既声明属性名索引,也声明具体的单个属性名。如果单个属性名符合属性名索引的范围,两者不能有冲突,否则报错。 image.png

建议谨慎使用属性的索引类型写法,因为属性名的声明太宽泛了,约束太少。

另外,属性名的数值索引不宜用来声明数组,因为采用这种方式声明数组,就不能使用各种数组方法以及length属性,因为类型里面没有定义这些东西。 image.png

解构赋值

结构赋值用于直接从对象中提取属性。 image.png

解构赋值的类型写法,跟为对象声明类型是一样的。 image.png

注意,目前没法为结构变量指定类型,因为对象结构里面的冒号,JS指定了其它的用途。 image.png

这里要特别注意。 image.png

结构类型原则

只要对象B满足对象A的结构特征,TS就认为对象B兼容对象A的类型,这称为“结构类型”原则。 image.png

根据“结构类型”原则,TS检查某个值是否符合指定类型时,并不是检查这个值的类型名(即“名义类型”),而是检查这个值的结构是否符合要求(即“结构类型”)。

TS这样设计是为了符合JS的行为。JS并不关心对象是否严格相似,只要某个对象具有所要求的属性,就可以正确运行。

如果类型B可以赋值给类型A,TS就认为B是A的子类型,A是B的父类型。子类型满足服类型的所有结构特征,同时还具有自己的特征。凡是可以使用父类型的地方,都可以使用子类型,即子类型兼容父类型。

image.png

严格字面量检查

如果对象使用字面量表示,会触发TS的严格字面量检查。如果字面量的结构跟类型定义的不一样(比如多出了未定义的属性),就会报错。 image.png

如果等号右边不是字面量,而是一个变量,根据结构类型原则,是不会报错的。 image.png

TS对字面量进行严格检查的目的,主要是防止拼写错误。 image.png

规避严格字面量检查,可以使用中间变量。 image.png

如果确认字面量没有错误,也可以使用类型断言规避严格字面量检查。 image.png

如果允许字面量有多余属性,可以像下面这样在类型里面定义一个通用属性。 image.png

编译器选项suppressExcessPropertyErrors可以关闭多余属性检查。 image.png

最小可选属性规则

如果一个对象的所有属性都是可选的,会触发最小可选属性规则。 image.png

即使使用中间量赋值也无法规避规则。 image.png

空对象

空对象是TS的一种特殊值,也是一种特殊类型。 image.png

空对象只能使用继承属性,即继承自原型对象Object.prototype的属性。 image.png

先声明一个空对象再向空对象添加属性,是JS常见的写法。但是,TS不允许动态添加属性,所以对象不能分步生成,必须生成时一次性声明所有属性。 image.png

如果确实需要分布声明,一个比较好的方法是,使用扩展运算符(...)合成一个新的对象。 image.png

空对象作为类型,其实是Object类型的简写形式。 image.png

因为Object可以接受各种类型的值,而空对象是Object类型的简写,所以它不会有严格字面量检查,赋值时总允许多余的属性,只是不能读取这些属性。 image.png

如果想强制使用没有任何属性的对象,可以采用下面的写法: image.png