型別斷言,也可以稱為型別轉換,是一種告訴 TypeScript 編譯器「相信我,我知道這個值的型別是什麼」的機制。它類似於其他程式語言中的型別轉換,但在 TypeScript 中,它更為安全,因為它僅在編譯時起作用,不影響運行時的行為。
as
關鍵字<>
特別注意:尖括號 <>
在 React 中也存在類似的語法,為了避免與 JSX 語法產生衝突,TypeScript 提供的替代方式是使用 {}
和 as
一起,以確保 JSX 語法和型別斷言不會衝突。
非空斷言運算子是 TypeScript 中的一個特殊運算子,它用來告訴 TypeScript 我們確信某個表達式的值不會是 null
或 undefined
。這個運算子以 !
表示。
未使用 !
:
function numberTransformString(value: number | null) {
console.log(value.toString()); // TypeScript 報錯,'value' 可能為「null」或「未定義」。
}
numberTransformString(123);
使用 !
:
function numberTransformString(value: number | null) {
console.log(value!.toString()); // 通過,字串型別的 123
}
numberTransformString(123);
HTML 現在包含一個 <p>
標籤。接著,我們使用選擇器來抓取這個 <p>
標籤的 DOM 元素,將它賦值給了 paragraph
變數。當我們將滑鼠懸停在 paragraph
變數上時,我們可以觀察到 TypeScript 推斷出 paragraph
的型別可能是 HTMLParagraphElement
或 null
。這是因為在頁面中,這個元素可能不存在;值得注意的是,TypeScript 實際上能夠辨識出這是一個段落元素。
<p>一起學習 TypeScript 吧!</p>
const paragraph = document.querySelector('p');
如果我們在 <p>
標籤上加上了一個 id
屬性,然後使用 getElementById
函式來選取該元素,我們會注意到 TypeScript 推斷這個元素只是一個 HTMLElement
或 null
,而不清楚具體是哪種 HTML 元素。這是因為 TypeScript 不會深入分析我們的 HTML,只知道它是某種 HTML 元素。
<p id="message-output">一起學習 TypeScript 吧!</p>
const paragraph = document.getElementById('message-output');
HTML 現在包含一個 <input>
標籤。接著,我們嘗試抓取這個 DOM 元素並嘗試賦值給它,但注意到 TypeScript 產生了一些錯誤。
<input type="text" id="user-input" />
const userInput = document.getElementById('user-input');
userInput.value = '我是肉鬆'; // TypeScript 報錯
// 錯誤一: 'userInput' 可能是 'null'
// 錯誤二: 類型 'HTMLElement' 沒有屬性 'value'
getElementById
這樣的 DOM 選取方法時,它們的返回型別通常是 HTMLElement
或 null
。這是因為根據指定的 id 可能找不到對應的元素,因此返回值可以是 null
。userInput
變數的型別是 HTMLElement
,而 HTMLElement
並不一定具有 value
屬性。為了解決這個問題,需要使用型別斷言,明確告訴 TypeScript userInput
的型別是 HTMLInputElement
,因為我們知道它實際上是一個 input
元素。解決方法一:使用 !
搭配尖括號 <>
。
const userInput = <HTMLInputElement>document.getElementById('user-input')!;
userInput.value = '我是肉鬆';
解決方法二:使用 !
搭配 as
關鍵字。
const userInput = document.getElementById('user-input')! as HTMLInputElement;
userInput.value = '我是肉鬆';
解決方法三:使用條件判斷式搭配 as
關鍵字。
const userInput = document.getElementById('user-input');
if (userInput) {
(userInput as HTMLInputElement).value = '我是肉鬆';
}
特別注意:要將表達式用括號 ()
括起來,確保先計算表達式,然後才嘗試存取這個表達式結果的值。這是確保型別斷言正確運作的重要步驟。
as
關鍵字或尖括號 <>
來執行。!
來告訴 TypeScript 忽略可能的 null
或 undefined
。null
或 undefined
的屬性或方法之前,請使用括號 ()
將表達式括起來,以確保型別斷言正確運作。