- Published on
「TS筆記」非空斷言操作符(!)
- Authors
- Name
- Wen Chen
非空斷言操作符(Non-null Assertion Operator)
非空斷言操作符雖說長得跟我們熟悉的 ?.
(optional chaining operator) 很像,但非空斷言操作符(!.) 是 TypeScript 專屬的語法。
就如同字面上的意思,!
讓開發者可以透過 !
,強制告訴 compiler 這個變數的值不會是 null
或是 undefined
,讓我們在操作變數的時候,不會出現可能是 null 的錯
Object is possibly 'null' or 'undefined'.
使用情境
我們先看一下底下的程式碼:
function greet( name: string | null = "Wen") {
console.log(`Hello, ${name.toUpperCase()}!`);
}
上面的程式碼,雖然說我們在 name
給予了初始值,但還是會出現以下的錯誤:
'name' is possibly 'null'.
原因便在於,雖然我們有給予預設值,但他的型別還是有可能出現 null
,所以假如我們可以確定不會有 null
或 undefined
的情況發生,我們可以將程式碼改成:
function greet( name: string | null = "Wen") {
console.log(`Hello, ${name!.toUpperCase()}!`);
}
greet(); // "Hello, WEN!"
這樣便可以斷言 name
輸入值不會有 null
或 undefined
的情境,且因為有預設值,greet
也可以順利運作。
十分注意!
就使用上來說,非空斷言操作符
在使用上,其實有點像 ignore
的感覺,斷言這個值不會有 null
或 undefined
,但如我們在沒有確定的情況下,編譯時發現該值是 null
或 undefined
的話還是會爆掉的,所以還是要謹慎使用。
function greet( name?: string | null ) {
console.log(`Hello, ${name!.toUpperCase()}!`);
}
greet();
// [ERR]: "Executed JavaScript Failed:"
// [ERR]: Cannot read properties of undefined (reading 'toUpperCase')
這麼危險,為什麼還需要他 ?
看到這裡,可能很多人會想:
聽起來很可怕,那為什麼不好好寫 Code 就好?
實際上,很多時候我們會用一些現成的函數,或是用某些從套件取出的變數,有時候我們明知道該變數不可能為空值,但現實就是那現成的函數/元件我們改不了,!
便是提供我們用更方便的告訴 TS 這東西肯定不會為空值。
當然我們也可以透過 if
判斷變數為空值才執行,這樣也可以達到一樣效果,但用 !
可以少寫很多程式碼,在這時候就很方便了。
就如同前面提到的,當我們加上 !
,就等同於告訴 TS :「 現在由我來檢查型別,我說有那他就有!」,而這也意味著我們要為自己的行為負責,假設我們再加上 !
之後導致 Null Pointer Exception
,那就不是 TS 的問題了。