型別斷言是 TypScript 的一種機制,允許我們手動指定一個明確的型別,提供 TypeScript 編譯器無法自行推斷的額外型別資訊。
我們可以透過這兩種寫法來指定型別斷言:
<>
(angle-bracket)語法語法:<type>value
- 在需要斷言的變數前加上 <Type>
即可
as
語法語法:value as type
需注意,在 tsx
語法(React jsx
語法的 ts
版)中必須使用 as
寫法。
由於尖括號 <>
在 JSX 語法中表示一個標籤的開始,TypeScript 無法分辨尖括號是用於 JSX 元素還是型別斷言亦或是泛型,因此在 tsx
文件中需使用 as
寫法來避免這種衝突。
當我們在處理一些能夠知道比 TypeScript 型別推斷還要多的型別資訊時,型別斷言可以讓我們更準確地指定型別,確保程式碼的可讀性、可靠性和可維護性。
當我們從 DOM 中獲取元素時,通常 TypeScript 只知道它是 HTMLElement
或其子類型,但我們可能更確定它的具體型別。這時就可以使用型別斷言來更準確地指定型別:
在這個例子中,我們使用 document.getElementById
來選取頁面上的元素,TypeScript 只知道會回傳某種 HTMLElement
,但並不知道是哪一種。
如果我們知道選取的會是哪一種類型的 HTMLElement
,就可以更明確地指定它可能是 HTMLInputElement
類型的元素。
any
型別當我們在處理一個 any
型別的值時,可能需要將其斷言為更具體的型別。這樣可以避免在後續的程式碼中使用額外的型別檢查和警告。
使用聯合型別時,當 TypeScript 無法確定一個聯合型別的變數到底是哪個型別的時候,我們只能取用此聯合型別的所有型別裡共有的屬性或方法。
但有時候我們會需要在還不確定型別的時候就訪問其中一個型別的屬性或方法。此時就可以使用型別斷言,將想要訪問的變數斷言成指定的型別:
在上面沒有使用型別斷言的例子中,因為 something
的型別有可能是 string
也有可能是 number
因此在取用 length
屬性時會報錯( number
沒有 length
屬性)。
我們透過型別斷言 <string>something
將變數 something
斷言為 string
型別。取用 length
屬性是沒問題的。
當我們們使用外部 API 或第三方套件時,返回的數據可能會包含不同的型別。此時,我們可以使用型別斷言來確保程式碼使用正確的型別。
使用型別斷言 response.data as {name: string, age: number}
時,編譯器可以提供其屬性及方法的提示。
確定一個變數一定不會是 null
或 undefined
時,可以使用非空斷言 !
。
在使用型別斷言時,必須確保有足夠的理由和型別資訊來進行斷言,否則可能會造成意料之外的錯誤。此外,也應該在適當的時候選擇使用更強大的 TypeScript 功能,例如型別定義和聯合型別。