本文介绍TypeScript的高级类型。包括:类型别名, 类型联合和类型交叉,以及字面值类型,Nullable(可空)、unknown、never等类型。
类型别名
看一下employee对象。
有三个问题,第一,创建employee其他对象时,我们必须重要写这个结构;第二, 其他对象未必是一样的结构,因为不在同一个地方定义employee结构;第三,代码也比较难理解。所以就有了类型别名(Type aliases)。
我们用type关键字自定义一个类型,类型名用Pascal命名法即首字母大写。
联合类型
变量或函数的参数不是确定的类型,可能是某些类型的一种,可以使用联合类型。各类型之间用竖线分隔,表示变量或参数是其中的一个类型。
我们用typeof判断类型。
编译成JavaScript代码,我们会发现,联合类型不是生成的JavaScript的一部分,它仅由编译器使用。
交叉类型
联合类型是参数或变量是其中的一个类型,而交叉类型则表示同时属于两个类型,它用 & 来分隔。从技术上来讲,某个变量不可能既属于number 又属于 string,我们来看一个现实的例子。
字面量类型(Literal Type)
有时需要限制只允许某些值,可以使用Literal Type。比如我们只允许quantity为50或100。
type Quantity = 50 | 100;
let quantity: Quantity =100
如果quantity设置为101,将会出错。字面量类型不一定是数字,也可以是字符串。
type Metric = ‘cm’ | ‘inch’;
可空类型(Nullable Type)
TypeScript对于使用null或undefinde非常严格,因为这是常见错误的源头。 默认情况下,TypeScript配置了”strictNullChecks”:true 限制空值。
如果允许传递 null 或 undefined,该如何处理?
用联合类型,将null和undefined类型放入即可!
可选链接(Optional Chaining)
返回可空的类型时,根据现有的知识,需要判断是否为空,不为空才作进一步处理。使用可选链接( ? . )可以简化这个步骤。
在使用数组时,有时需要判断数组是否为空,也可使用可选链接。
customers?.[0]
在函数中也是可以使用Optional Chaining的,比如定义一个log函数。
let log:any = (message:string)=>console.log(message);
调用的话就是 log(‘a’);
但log也可能是null如
let log:any = null;
再调用log(‘a’)程序就会崩溃,可以使用 ?.
log?.(‘a’)
空值合并运算符(Nullish Coalescing Operator)
有时需要判断是否空 null 或 undefined。但在JavaScript中,Falsy值包括 undefined, null, ”, false, 0 ,通过判断是否Falsy的方式是不行的。所以出现了空值合并运算 ??
?? 运算只检测是否是null或undefined,这就是我们想要的。
类型断言(Type Assertions)
有时我们比TypeScript更知道对象的类型,可以使用类型断言,关键字是as。
上图,网页里有个Input元素名为phone,用getElementById返回的是HTMLElement类型,没有我们想要的value属性。我们知道该元素是HTMLInputElement类型,于是用关键字 as 断言它是HTMLInputElement类型。
在TypeScript中,as 关键字不执行类型转换,这跟其它语言是不同的。它仅仅告诉编译器我们更知道该对象的类型,当返回的对象实际不是as 断言的类型时,是不会抛出异常的。
但当我们执行时,比如实际不是HTMLInputElement类型,我们却调用它的属性value时,程序将会崩溃。
除了 as 关键字,还有一种语法,就是加上尖括号的前缀,也能达到这个效果。
Unknown类型
前面我们谈到过any类型。使用any类型,可以调用任何方法和属性,但如果实际不存在,应用程序将崩溃,一般而言,尽量避免使用any类型。
与any 类型类似,还有一种类型叫 unknown, 如果我们将上图的any类型改成unknown类型,将立即看到编译错误,这将促使我们进行类型检查,这对避免错误是有好处的。
内置类型的检查用 typeof ,对自定义的对象和类,可以使用 instanceof 来检查,这个等后面文章谈到类的时候再讲。
总之,我们尽量使用 unknown类型,避免使用 any 类型,因为前者促使我们做一些类型检查保证目标对象确实存在调用的方法或属性。
Never类型
never类型表示该值永不会发生,这不太常见,我们来看个例子。
我们假设precessEvents监视消息队列并进行处理,显然它永远不会返回值 ,因为有一个无限循环在里面。我们指示该函数返回为never。
tsconfig.json配置
“allowUnreachableCode”: false,
这样的话,最后一句就会有一个警告,提醒该语句永远不会被执行。
再来看另一个例子。
reject函数明显不会返回,所以我们也应声明返回never。
总之,never不常用,但我们需要了解它。
小结
本文介绍TypeScript的类型别名、类型联合、类型交叉、字面量类型,以及Nullable(可空)、unknown、never等类型。
下一篇介绍TypeScript的类、接口以及面向对象编程。