TypeScript基礎入門之高級類型的可null類型

轉發ide

TypeScript基礎入門之高級類型的可null類型

高級類型

可null類型(Nullable Types)

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的類型。

相關文章
相關標籤/搜索