7 個好用的 TypeScript 新功能

  • 2020 年 1 月 14 日
  • 筆記

TypeScript 語言小組一直在以驚人的速度推出新功能。從最新的《 Javascript 語言狀況調查》(https://2019.stateofjs.com/javascript-flavors/typescript/)中可以看出,該語言的使用率越來越高。

本文將會總結你應該使用的最重要的功能。我會重點介紹以下最新版本的功能:

注意:在探究這些功能之前,你應該先去看一下 TypeScript playground,在這裡可以測試所有的功能。我建議你切換到較舊的版本(單擊左上角的版本下拉列表),來查看較新的版本是怎樣處理以前不支援的用例的:

02

1.可選鏈

從 v3.7 可用

這是當你嘗試訪問嵌套數據時的一個痛點,嵌套數據越多,程式碼就會變得越繁瑣。

在下面的例子中,要訪問 address,你必須遍歷 data.customer.address,而且 data 或 customer 有可能是 undefined,所以通常使用 && 運算符或類似例子中的技巧遍歷檢查每個層次的定義。

現在你可以用 .? 運算符來選擇性地對數據訪問。通過這種方式,如果存在尚未定義的父級對象,則會在鏈中的任何位置返回未定義,而不是在運行時崩潰。

// v3.7 以前  if (data && data.customer && data.customer.address) {     const {address} = data.customer     const fullAddress = `${address.street}, ${address.city}, ${address.state }${address.zipcode}`  }    // v3.7    // data access  const address = data?.customer?.address  const fullAddress = `${address?.street}, ${address?.city}, ${address?.state } ${address?.zipcode}`    // 也適用於數組  customers?.[0]?.['address']    // 檢查方法是否已定義並調用  customer.approve?.()  

02

2.空值合併

從 v3.7 可用

空值合併運算符是 || 的替代方法,如果左側是 null 或 undefined,則它返回右側的表達式。這和 || 有什麼不同? || 本質上是 JavaScript 中的布爾 OR 運算符,我們嘗試利用短路返回第一個非 false 值。這可能會產生意想不到的結果,因為當要求數字 0 或空字元串作為有效輸入時,將會被視為 false。讓我們用一個例子來說明:

// 以前  passPhrase = data.inputString || 'Unknown'  //不會接受 "" (空字元串)  passCode =  data.number || '-1111' // 不會接受 0  rememberMe = data.rememberFlag || true // 將會總是 true!!!      // 現在  passPhrase = data.inputString ?? 'Unknown'  //僅在 inputString 未定義時為 Unknown  passCode =  data.number ?? '-1111' // 0 可以通過  rememberMe = data.rememberFlag ?? true // false 是有效值  

通過這種方式可以明確地區分 undefined 與 false 的值。

02

3.遞歸類型別名

從 v3.7 可用

現實世界中的很多數據類型都是遞歸的。例如,當你嘗試處理分層數據時,會發現存在相同類型數據的重複模式。JSON 是一個很好的例子,它本質上是一個哈希映射,而哈希映射本身可以包含另一個映射或映射數組。

在 v3.6 之前,如果必須定義一個簡單的 JSON 類型,則必須像下面這樣:

interface JSONObject { [x: string]: JSONValue; }  interface JSONArray extends Array<JSONValue> { }  type JSONValue = string | number | boolean | JSONObject | JSONArray  

如果你嘗試將第 1 行和第 2 行的類型在像第 3 那樣內聯,則可能會出現以下錯誤:Type alias JSONValue circularly references itself。

在 v3.7 中已經有效解決了這個問題,可以像下面這樣簡單地進行編碼:

type JSONValue = string | number | boolean | { [x: string]: JSONValue } | Array<JSONValue>  

02

4.斷言簽名

從 v3.7 可用

你應該知道 TypeScript 具有類型保護,可以很好地與 JavaScript 中的 typeof 和 instanceOf 運算符一起使用。這有助於為函數的參數添加前提條件,以便將其限制為特定的類型。

讓我們寫一段把上面提到的這些東西都用到的程式碼,通過添加類型保護來確保給定的輸入是日期,並從中提取年份:

function isDate(input: unknown) : asserts input is Date {    if (input instanceof Date)      return;    else      throw new Error('Input must be a Date!');  }    function getYear(input: unknown) : number {    isDate(input);    return input.getFullYear()  // TypeScripts knows that input is Date  }      console.log(getYear(new Date('2019-01-01')));  console.log(getYear('2019-01-01'));  

上面的程式碼看起來很不錯,但 TypeScript 仍然會提示getFullYear 在未知類型上不可用。

從 v3.7 開始,TypeScript 添加了一個名為 asserts 的新關鍵字,它能夠使編譯器從斷言起就知道正確的類型。對於斷言函數,應該添加 asserts <param> as <type> 而不是返回類型。

這樣,如果斷言通過,TypeScript 將假定參數是前面定義的類型。修改後的程式碼如下所示:

function isDate(input: unknown) : asserts input is Date {    if (input instanceof Date)      return;    else      throw new Error('Input must be a Date!');  }    function getYear(input: unknown) : number {    isDate(input);    return input.getFullYear()  // TypeScripts knows that input is Date  }      console.log(getYear(new Date('2019-01-01')));  console.log(getYear('2019-01-01'));  

02

5.為Promise提供更好的回饋

從 3.6 起改進

在程式碼中直接使用 Promise 而忘記使用 await 或 then 是常見的錯誤,如下所示:

}

以前的 TypeScript 完全不了解 Promise,並顯示一條與其無關的錯誤消息,如下所示:

從 v3. 6 開始,編譯器變得非常聰明,可以建議你應該兌現 Promise。注意最新的編譯器是如何處理相同的錯誤的:


下面簡單討論一下不需要深入了解細節的一些功能:

02

6.Unicode 標識符

從 v3.6 可用

const ????? = "world"  

上面的程式碼可能不能夠在早期版本的 TypeScript 上編譯,但是現在你可以從更廣泛的 unicode 集中定義標識符。

02

7.增量編譯

從 v3.4 起可用

如果你在大型項目上使用 TypeScript,則編譯器可能需要很長時間才能響應你對該代項目中文件所做的更改。現在有了新的 --incremental 標誌,你可以將其添加到 tsc(typescript 編譯器)命令行中,這個命令行將會遞增地編譯修改過的文件。

TypeScript 通過把自從上次編譯以來的項目資訊保存在程式碼庫內的本地快取目錄中來實現這一目的。在 React 程式碼庫上,一定要記住在 Webpack 或 Parcel 進行正確的配置,這樣才能在構建管道中利用增量編譯。

TypeScript是為大型應用之開發而設計,作為一個前端工程師,TypeScript 是必備技能,目前TypeScript 已在Node.js 、Angualr、React、Vue這些框架中廣泛應用,已經成為大型項目的標配。

但是,市面上的 TypeScript 教程千篇一律,大多是從官網複製粘貼,如果要學習 TypeScript 語法細節,一定要找真正優質的教程。

Tags: