typescript 3.7 中值得注意的 3 个新特性

写在前面

typescript 3.7 正式发布已经有一段时间了,这段时间正在对手上的项目进行 typescript 的迁移工做,因此会特别留意每一次的 releasejavascript

对于 3.7 中包含的新特性,其实相比较以前几回 release 来讲,算是一个比较小的发布版本,可是其中包含的几个特性对代码质量自己,会带来显著地提高。java

Optional Chaining

首先第一个特性是对于 optional chaining 操做符的支持,翻译过来应该能够叫作可选链操做符,固然我仍是以为这样翻译有点怪怪的,暂且就直接用英文好了。typescript

这个特性首先是 es2019 中包含的一个新特性,对于特性自己,有兴趣的能够参考这里json

因为 typescriptjavascript 的超集,因此预先实现这个特性也是在预料以内的事情,大概使用方式是这样的:安全

a?.b();
复制代码

等价于:bash

if(a) a.b();
// 或者
a && a.b()
复制代码

若是是多层嵌套,好比 b 也是一个对象,要继续调用 c(),那么能够这样:ui

a?.b?.c()
复制代码

但其实就算这样写的话,它也不是安全的,由于 b() 中的 b 也有多是空值,直接调用的话,也会抛出异常。为了绝对的安全,能够这样写:spa

a?.b?.();
复制代码

值得注意的是,这里必定要对于可选的含义有一个正确的理解,可选的意思是,它在类型的声明中,经过 ? 来修饰,表明一个类型包含某个可为空值的属性。言外之意的意思就是,?. 不会对那些不符合类型声明自己的属性调用,好比:翻译

interface A {}

const a: A = {};

a?.b?.(); // Property 'b' does not exist on type 'A'
复制代码

除非 A 接口的声明改成:debug

interface A {
  b?: any
}
复制代码

这个特性在项目的实践意义是很大的,咱们能够写更少的 if 断言语句或者 && 操做符,可是却达到了相同的效果。

Nullish Coalescing

中文翻译过来会叫作双问号操做符,这个其实挺形象的,由于它的语法确实就是 ??

这个操做符的功能,往简单说,就是为一个空值,指定一个默认值,相似下面的代码:

let a = b || 'foo'
复制代码

b 为空值时,因为 || 操做符的特性,a 的值会被赋予 foo。若是使用 ?? 操做符进行改写,以下:

let a = b ?? 'foo'
复制代码

表面上看,彷佛二者没什么区别,但其实这里隐含了一个问题,就是 || 对于空值的概念,并不只仅指 nullundefined,相似 false0 等一系列逻辑上为 false 的值都会算做空值,这显然是有问题的,好比:

const b = 0
let a = b || 'foo'
// a 为 'foo'
复制代码

这个示例中,咱们指望 a 只有在 b 为真正意义上的空值(null 或者 undefined)时,才被赋予默认值,a 应当等于 0,而实际运行结果确实 foo,由于 b=0,在 || 操做符的运行过程当中,它会被解释为 false。我曾在实际项目中,编写过一个验证码组件,很不幸,踩上了这个坑,当时为了 debug 这个问题,花了很长时间。

但使用 ?? 操做符,就不会存在这个问题。

Uncalled Function Checks

我相信不少人都曾经遇过相似的问题,由于缺少有效的命名规范,断言属性和断言方法会在实际项目中被混用,好比:

class A {
    isFoo(): boolean {
        return false;
    }
}

function test(a: A) {
    if (a.isFoo) { 
        ...
    } 
}
复制代码

这里若是咱们的本意是要经过调用 a.isFoo 来获取一个断言值,咱们明显犯了一个错误,咱们应当使用 if (a.isFoo()),而不是直接 if (a.isFoo),由于后者虽然在语法层面没有错误,可是在逻辑含义,它将被断言为 true。但在 3.7 发布以后,typescript 会尝试帮助咱们发现这个问题。

虽然如此,但我仍然建议你们针对断言方法和断言属性制定统一的命名规范,好比 isXXX 表明属性,而 assertXXX 表明方法。

其余

其余的一些变动,均是易用性上的一些改变,好比:

  • Flatter Error Reporting:会将一大段的类型重复的错误日志,尽量地压缩为单条、更准确、更精简的错误日志
  • 文件级别的 @ts-nocheck:以前版本中该注解仅支持行内级别
  • 递归类型声明:可以在类型声明中,使用递归语法来声明更复杂的类型,好比 json 类型
  • js 文件提供 declaration 支持,以减少从 js 项目迁移的迁移成本

关注公众号 全栈 101,只谈技术,不谈人生

相关文章
相关标签/搜索