轉發ide
TypeScript具備兩種特殊的類型,null和undefined,它們分別具備值null和undefined。 默認狀況下,類型檢查器認爲null與undefined能夠賦值給任何類型。
null與undefined是全部其它類型的一個有效值。 這也意味着,你阻止不了將它們賦值給其它類型,就算是你想要阻止這種狀況也不行。
null的發明者,Tony Hoare,稱它爲價值億萬美金的錯誤。函數
--strictNullChecks標記能夠解決此錯誤:當你聲明一個變量時,它不會自動地包含null或undefined。
你可使用聯合類型明確的包含它們,以下post
let s = "foo"; s = null; // 錯誤, 'null'不能賦值給'string' let sn: string | null = "bar"; sn = null; // 能夠 sn = undefined; // error, 'undefined'不能賦值給'string | null'
注意,按照JavaScript的語義,TypeScript會把null和undefined區別對待。
string | null,string | undefined和 string | undefined | null是不一樣的類型。spa
使用了 --strictNullChecks,可選參數會被自動地加上| undefined:code
function f(x: number, y?: number) { return x + (y || 0); } f(1, 2); f(1); f(1, undefined); f(1, null); // error, 'null' is not assignable to 'number | undefined'
可選屬性也會有一樣的處理:blog
class C { a: number; b?: number; } let c = new C(); c.a = 12; c.a = undefined; // error, 'undefined' is not assignable to 'number' c.b = 13; c.b = undefined; // ok c.b = null; // error, 'null' is not assignable to 'number | undefined'
因爲能夠爲null的類型是經過聯合類型實現,那麼你須要使用類型保護來去除 null。 幸運地是這與在JavaScript裏寫的代碼一致:ip
function f(sn: string | null): string { if (sn == null) { return "default"; } else { return sn; } }
這裏很明顯地去除了null,你也可使用||運算符:get
function f(sn: string | null): string { return sn || "default"; }
若是編譯器不可以去除null或undefined,你可使用類型斷言手動去除。 語法是添加!後綴:identifier!從identifier的類型裏去除了null和undefined:編譯器
先看第一個失敗的例子string
function broken(name: string | null): string { function postfix(epithet: string) { return name.charAt(0) + '. the ' + epithet; // error, 'name' is possibly null } name = name || "Bob"; return postfix("great"); }
在看下第二個成功的例子
function fixed(name: string | null): string { function postfix(epithet: string) { return name!.charAt(0) + '. the ' + epithet; // ok } name = name || "Bob"; return postfix("great"); }
上面的例子使用了嵌套函數,由於編譯器沒法去除嵌套函數的null(除非是當即調用的函數表達式)。 由於它沒法跟蹤全部對嵌套函數的調用,尤爲是你將內層函數作爲外層函數的返回值。 若是沒法知道函數在哪裏被調用,就沒法知道調用時name的類型。