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,只談技術,不談人生

相關文章
相關標籤/搜索