typescript中的 null 和 undefined


null 和 undefined 是 ts 中的基礎類型,分別具有值 null 和 undefined,默認情況下它們是所有類型的子類型,即可以賦值給任意類型,如:

let s: string = 'hello'

s = null //right
s = undefined // right

但當我們在 tsconfig.js 文件中設置 strictNullChecks 為 true 時,就不能將 null 和 undefined 賦值給除它們自身和 void 之外的任意類型了。在這種嚴格檢查的情況下,如果你確實在某個地方想要給一個其他類型的值設置初始值為空,然后再賦值,可以使用聯合類型來實現:

// 開啟 "strictNullChecks": true 情況

let s: string = 'hello'
s = null // error,不能將類型“null”分配給類型“string”。

let s2: string | null = 'hi'
s2 = null
s2 = undefined // error,不能將類型“undefined”分配給類型“string | null”。

從例子中知道,null 和 undefined 是區別的,即 string|undefined、string|null 和 string|undefined|null 是三種不同的類型。

 

可選參數和可選屬性

如果設置了 "strictNullChecks": true,可選參數會被自動加上 |undefined,例子:

function f(x: number, y?: number){
    return x + (y || 0)
}
f(1, 2) // 3
f(1) // 1
f(1, undefined) // 1
f(1, null) // error,類型“null”的參數不能賦給類型“number | undefined”的參數。

對於可選屬性也會有同樣的處理:

interface PositionInterface{
    x: number
    y?: number
}

let p: PositionInterface = {x: 10}
p.y = 'abc' // error,不能將類型“"abc"”分配給類型“number | undefined”。

p.y = null // error,不能將類型“null”分配給類型“number | undefined”。

p.y = undefined // right

 

類型保護和類型斷言

可以為 null 的類型是通過聯合類型實現,所以需要使用類型保護去除 null,如:

function f(sn: string | null): string{
    if(sn === null){
        return 'null'
    } else {
        return sn
    }
}

這樣操作可以去除 null,或者使用短路運算符:

function f(sn: string | null): string{
   return sn || 'null'
}

 

如果編譯器無法去除 null 和 undefined,可以使用類型斷言手動去除。語法是添加 ! 后綴: identifier! 從 identifier 的類型里去除了 null和 undefined,官方例子:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM