科技速递|TypeScript 4.0发布,新增可变参数元组类型等( 四 )

type Bar = [first: string, number];// ~~~~~~// error! Tuple members must all have names or all not have names.
值得注意的是 , 标签不需要在解构时以不同的方式命名变量 。 它们纯粹是那里的文档和工具 。
function foo(x: [first: string, second: number]) {// ...// note: we didn't need to name these 'first' and 'second'let [a, b] = x;// ...}总的来说 , 带标签的元组在利用元组和参数列表周围的模式以及以类型安全的方式实现重载时很方便 。 实际上 , TypeScript的编辑器支持会在可能的情况下尝试将它们显示为重载 。
构造函数的类属性推断当noImplicitAny启用时 , TypeScript 4.0可以使用控制流分析来确定类中的属性类型 。
class Square {// Previously: implicit any!// Now: inferred to `number`!area;sideLength;constructor(sideLength: number) {this.sideLength = sideLength;this.area = sideLength ** 2;}}如果并非将构造函数的所有路径都分配给实例成员 , 则该属性可能被认为是undefined 。
class Square {sideLength;constructor(sideLength: number) {if (Math.random()) {this.sideLength = sideLength;}}get area() {return this.sideLength ** 2;// ~~~~~~~~~~~~~~~// error! Object is possibly 'undefined'.}}短路分配运算符JavaScript和许多其他语言一样支持一组称为复合赋值运算符的运算符 。 复合赋值运算符将一个运算符应用于两个参数 , 然后将结果赋给左侧 。 比如:
// Additiona += b;a -= b;a *= b;a /= b;a **= b;a <<= b;【科技速递|TypeScript 4.0发布,新增可变参数元组类型等】
JavaScript中的许多运算符都有对应的赋值运算符!但是仍然存在三个值得注意的例外操作符:逻辑和(a = a || b;a = a ?? b;或if块
// could be 'a ||= b'if (!a) {a = b;}甚至一些模式支持惰性初始化 , 只有在需要它们时才加载 。
let values: string[];// 之前(values ?? (values = [])).push("hello");// TS 4.0(values ??= []).push("hello");在极少数情况下使用带有副作用的getter或setter时 , 值得注意的是这些运算符仅在必要时执行赋值 。 从这个意义上讲 , 不仅操作符的右侧"短路"了 , 赋值本身也是如此 。
obj.prop ||= foo();// roughly equivalent to either of the followingobj.prop || (obj.prop = foo());if (!obj.prop) {obj.prop = foo();}catch语句中绑定unknown自TypeScript诞生以来 , catch子句变量始终为any 。 TypeScript允许对它们进行任何操作 。
try {// ...}catch (x) {// x has type 'any' - have fun!console.log(x.message);console.log(x.toUpperCase());x++;x.yadda.yadda.yadda();}如果试图防止在错误处理代码中发生更多错误 , 则上面的代码会有一些不良行为!因为这些变量any默认情况下具有类型 , 所以它们缺少类型安全性 , 这些类型安全性可能在无效操作上出错 。
TypeScript 4.0允许指定catch子句变量的类型unknown 。 unknown比any它更安全 , 在对值进行运算之前 , 需要执行某种类型检查 。
try {// ...}catch (e: unknown) {// error!// Property 'toUpperCase' does not exist on type 'unknown'.console.log(e.toUpperCase());if (typeof e === "string") {// works!// We've narrowed 'e' down to the type 'string'.console.log(e.toUpperCase());}}
尽管catch默认情况下变量的类型不会更改 , 但将来可能会考虑使用新的模式标志 , 以便用户可以选择这种行为 。 同时 , 应该可以编写lint规则来强制变量具有或的显式注释 。


推荐阅读