TS 类型声明
前言
本文主要讲解 TypeScript 的基本数据结构,主要包括 JS 基本数据类型以及 TS 特有的数据类型。
JS 基本数据类型: string、number、null、undefined、boolean、array
TS 特有的数据类型:tuple(元祖)、enum(枚举)、any、unknow、never
注意: node
不能直接执行 ts 文件,需要先将 ts 编译成 js,然后再执行 js
一、 string、number、null、undefined、boolean 类型声明
JS 普通写法如下:
TS 写法如下:不能更改它们的变量类型,否则会直接报错
编译成 JS 后如下:
编译后为什么 let 会变成 var 呢?es6 是规范 但是还有很多浏览器不支持 所以编译完之后都是转义成 es5, es5 没有 let。并且需要在
tsconfig.json
中配置如下:
在这里插入代码片
- 错误示范:
二、 array、tuple(元组)
JS 数组和 TS 数组之间的区别
JS 中的数组可以是字符串、数字等其他类型的数据,而 TS 中的数组是纯数字类型(number
)的集合,如果在 TS 中定义包含多个类型的数组,那就是元组。
JS 写法如下:
TS 声明数组有多种方式,具体如下:
(1)数组的数据类型一致
Array<>:声明一个数组,数组类型为
<>
中定义的类型,比如:Array<string>
string[]:声明一个数组,数组类型为
[]
前定义的类型,比如number[]
(2)数组的数据类型不一致
联合数据声明:比如
(string|number)[]
,声明一个数组,数组类型为字符串、数字。数组中数据的类型可以不随定义的类型位置的限定。
(3)数组的数据类型任意
(4)限制类型和长度的元祖数组
tuple(元祖):是固定数量的不同类型的元素的组合,比如[number, string]
。数组中数据的位置、类型以及个数必须要和声明的类型、声明类型的位置、声明类型的个数保持一致,否则就会报错。
三、enum(枚举)
枚举主要分为数字类型枚举、字符串类型枚举、异构。语法:enum
+ 变量名,意思是定义了一个叫做“变量名”的枚举类型优点:定义一些常量,可以清晰地表达意图或创建一组有区别的用例。
(1)数字型枚举
含义:枚举成员都是 number 类型,如果没有对枚举对象中的枚举成员赋值,那么会默认从枚举对象中的第一个枚举成员的值是 0,并依次递增。
具有以下特点:
反向映射
枚举成员的值可以不用初始化
以上可知,我们既可以取到枚举成员的属性名,也能取到枚举成员的属性值,它们之间是相互映射的。
修改枚举成员的默认值
我们可以看到我们改变枚举成员的默认值的时候,后面枚举成员的默认值也随着前面的改变而改变。我们来看一下上面编译成 JS 后的样子,具体如下所示:
(2)字符串类型枚举
含义:枚举成员类型都是字符串需要注意以下几个方面:
字符串枚举没有反向映射,如果进行反向映射的话,取得的值时
undefined
;字符串枚举没有递增,需要对每一个字符串枚举类型成员进行赋值,即必须具有初始化表达式
以下是错误示范,不能对字符串类型枚举进行反向映射
(3)异构
含义:枚举类型包括字符串类型和数字类型注意:含有字符串值成员的枚举中不允许使用计算值,具体意思就是当枚举对象中存在有value
是字符串的枚举成员的时候,不能将其他枚举成员的value
设置为计算值。
上面的 TS 编译成 JS 后的样子如下所示:
我们用普通方法来实现异构枚举,demo 如下所示:
怎么实现以上的枚举呢?具体如下:
以上我们看出依然是数字类型的枚举成员可以进行反向映射,字符串类型的枚举成员不能反向映射。
注意以下是错误用法,因为含有字符串值成员的枚举中不允许使用计算值
(4)枚举成员的值的两种形式-计算值和常量
枚举对象中成员的value
有两种形式,计算值或者常量,怎么区分是计算值和常量呢?我们可以通过枚举成员表达式来判断,只要是枚举成员是表达式则为常量。枚举成员表达式的判断条件如下:
枚举表达式字面量(主要是字符串字面量或数字字面量)
对之前定义的常量枚举成员的引用
带括号的常量枚举表达式
一元运算符 ++、 --
常量枚举表达式是二元运算符 + 、-、*、/、%、<<、>>、&、|、^的操作对象。注意:如果求值后值为 NaN 或 Infinity,那么会在编译阶段报错。
常量 demo 如下:
计算值 demo 如下所示:
四、any(任意类型)
声明变量类型为any
时
编译时会绕过所有类型的检测,直接通过编译阶段的检查
可以任意访问属性的方法和属性
any
类型可以赋值给任意类型如果变量初始没有定义类型,默认为
any
;经过赋值后,TS 会根据赋值类型来标识变量的类型
any 在使用过程中就像一个潘多拉魔盒,即使使用了断言,也丧失了在静态类型检查阶段发现错误的可能性。
五、unknow(未知类型)
声明变量类型为unknow
时
安全性更高
它用于描述类型不确定的变量,这与
any
类型相似,但更安全,因为对未知值做任何事情都是不合法的unknown
类型只能赋值给any
和unknown
类型,any 类型可以赋值给任意类型unknown
,never
都不允许执行变量的方法以及访问内部属性在
unknown
没有被断言或细化到一个确切类型之前,unknown
不可以赋值给其它类型,除了它自己和any
外,当然也都是不允许在其上进行任何操作的。
错误示范:
虽然可以对unknown
类型的变量进行任意赋值,但是却不能执行任何操作,如何解决这个问题呢?可以缩小unknown
类型。具体如下所示:
我们可以用断言缩小未知范围或者可以用instanceof
来缩小变量的类型,强制让 ts 编译器相信我们在做什么操作
六、void(空类型)
声明对象类型为void
时
返回为空值
声明一个变量为void
时
只能将它赋值为 undefined 和 null,因此在定义函数的返回值为
void
时,也可return undefined/null
七、never(不存在的值类型)
never
类型表示永不存在的值的类型。具有以下特点:
never
类型是所有类型的子类型,即never
类型可以赋值给任何类型。其他任何类型均不是
never
类型的子类型,即其他类型均不可赋值给never
类型,除了 never 本身。即使 any 类型也不可以赋值给 never 类型。返回类型为
never
的函数中,其终点必须是不可执行的,例如函数过程中抛出了错误或者存在死循环。变量也可以声明为
never
类型,但其不能被赋值
设置变量类型为never
,表示永远不能执行完或者永远 Error,具体示例如下:
函数中出现了死循环,永远不能执行完,因此其函数类型为:() => never
函数中出现报错,不会执行到
return over
,因此其函数类型为:() => never
版权声明: 本文为 InfoQ 作者【不叫猫先生】的原创文章。
原文链接:【http://xie.infoq.cn/article/c758466975b9d1a34ad30ba5a】。文章转载请联系作者。
评论