還記得我在《2020 年 JavaScript 狀態調研報告小結》中提到的 2020 年全球開發者最喜歡的 JavaScript 寫法是什麼嗎?-- 沒錯!TypeScript!。鑑於在項目中使用 TypeScript 確實有如下種種好處:html
本篇文章將向您介紹 TypeScript 自 3.7 版本以來更新的一些實用特性,但願您的代碼能變得更加穩固,優雅。git
請注意,TypeScript 是 JavaScript 類型的超集,而非語法的超集,所以一些符合 JavaScript 語法規範的代碼,在 TypeScript 中卻可能報錯,例如:程序員
let x = 1 x = 'hello world'
所以,在現代工具鏈中,TypeScript 編譯器甚至不被用做編譯出指定版本 JavaScript 的工具(這一般是 babel 的工做),而是做爲一種更強大的代碼檢查工具被使用。可是隨着 TypeScript 版本的更新,一些新的 JavaScript 語法特性也逐漸被 TypeScript 支持,這使得開發者在一些場景下能夠擺脫 babel 編譯的過程,直接使用 TypeScript 編譯生成最終的代碼。github
自 3.7 版本開始,TypeScript 支持了目前在 stage 4 階段的 Optional Chaining ,Nullish Coalescing語法。typescript
自 3.8 版本開始,Typescript 支持了目前在 stage 3 階段的 Private Fields 語法。(經過底層使用 WeakMap 數據結構,該語法使得 JavaScript 類真正意義上擁有「私有屬性」)編程
class Foo { #bar }
同時,該版本還支持了 namespace exports 語法:後端
export * as utils from './utils'
自 4.0 版本開始,TypeScript 支持自動推導 class 中的屬性類型,無需再顯示聲明。babel
TypeScript 4.0 開始支持兩種新的元組類型聲明方式:數據結構
type Foo<T extends any[]> = [boolean, ...T, boolean]
經過這種聲明方式,咱們能夠更精確的定義一個函數參數類型,在使用函數式編程時,這種定義方式就頗有用。編輯器
const Address = [string, number] function setAddress(...args: Address) { // some code here }
當咱們這樣定義函數入參後,在使用函數時,編輯器的智能提示只會提示咱們參數類型,丟失了對參數含義的描述。爲了改善這一點,咱們能夠經過 Labeled tuple types,咱們能夠這樣定義參數:
const Address = [streetName: string, streetNumber: number] function setAddress(...args: Address) { // some code here }
這樣,在調用函數時,咱們的參數就得到了相應的語義,這使得代碼更加容易維護。
自 Typescript 3.7 開始,咱們終於得到了只用一條類型聲明聲明 JSON 數據的能力:
type JSONValue = | string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue }
// @ts-expect-error
TypeScript 3.9 給出了一個替代 // @ts-ignore
註釋的方案:// @ts-expect-error
。
從字面上咱們不難理解爲何後者是更優的選擇:
unknown
類型讓咱們想一想這段代碼會最終打印出什麼:
try { willThrowAnError() } catch (err) { console.log(typeof err.message) }
答案是 "string"
嗎,並不是如此!由於 err.message
的值有多是 undefined
,甚至有可能在這裏拋錯,這取決於咱們的函數 willThrowAnError
內部是如何定義的:
// err.message => undefined function willThrowAnError() { throw 'hello world' } // err.message => throw an Error! function willThrowAnError() { throw null }
雖然第二種狀況幾乎不會發生,但這兩個示例說明了 catch
參數類型的不肯定性(所以在 TypeScript 中,它的默認類型是 any
)。
所以,在 TypeScript 4.0 中,提供了 unknown
類型供咱們處理這些咱們「不知道」的類型。不一樣於 any
類型,unknown
是 TypeScript 中的第一類型,能夠在任何地方使用。
子曰:知之爲知之,不知爲不知。
自 TypeScript 3.7 開始,支持基於 return/throw
的類型斷言。
function assertIsArray(val: any): asserts val is any[] { if (!Array.isArray(val)) throw new Error(`${val} is not an array`) }
這將讓測試變得更加容易。
點擊此處瀏覽相關文檔
自 TypeScript 3.8 開始,TypeScript 支持僅引入模塊類型:
import type { SomeThing } from "./some-module.js"; export type { SomeThing };
這樣作的好處在於,當某個模塊中包含反作用代碼時,用戶若是直接引入模塊,就會無心間執行反作用代碼,但當經過聲明只引入類型時,則避免了這個隱患。
點擊此處瀏覽相關文檔。
至此,本篇文章帶您快速瀏覽了 TypeScript 3.7 以來一些實用性強的新特性,不知道您是否學有所獲?TypeScript 將在 2021 年 5 月 25 日發佈 4.3 版本,屆時會新增哪些有意思的新特性?且聽下回分解:)