TypeScript Never 與 Unknown

TypeScript Never 與 Unknown

本節介紹 never 和 unknown 類型,其中 unknown 類型作爲 any 類型對應的安全類型使用起來更加安全,如果有 any 類型的使用需求,應儘量使用 unknown 類型來替代 any 類型。

1. 慕課解釋

never 類型表示那些永不存在的值的類型。

unknown 類型是 any 類型對應的安全類型。

2. never 類型

never 類型是任何類型的子類型,也可以賦值給任何類型;然而,沒有類型是 never 的子類型或可以賦值給 never 類型(除了 never 本身之外)。 即使 any 也不可以賦值給 never。

2.1 應用場景

一個拋出異常的函數表達式,其函數返回值類型爲 never:

function error(message:string): never {
  throw new Error(message)
}

同樣的,不會有返回值的函數表達式,其函數返回值類型也爲 never:

// 推斷的返回值類型爲 never
function fail(): never {
    return error("Something failed")
}

不能取得值的地方:

interface Foo {
  type: 'foo'
}

interface Bar {
  type: 'bar'
}

type All = Foo | Bar

function handleValue(val: All) {
  switch (val.type) {
    case 'foo':
      break
    case 'bar':
      break
    default:
      // 此處不能取值
      const exhaustiveCheck: never = val
      break
  }
}

代碼解釋: 代碼中所用到的接口聲明(interface)、類型別名(type)、聯合類型(A | B)之後都有專門小節介紹。

3. unknown 類型

我們知道 any 無需事先執行任何類型的檢查:

let value: any

value = true             // OK
value = 10               // OK
value = "Hello World"    // OK
value = []               // OK
value = {}               // OK
value = Math.random      // OK
value = null             // OK
value = undefined        // OK
value = new TypeError()  // OK
value = Symbol('name')   // OK

value.foo.bar            // OK
value.trim()             // OK
value()                  // OK
new value()              // OK
value[0][1]              // OK

在許多情況下,這太寬鬆了。 unknown 類型呢?

let value: unknown

value = true             // OK
value = 10               // OK
value = "Hello World"    // OK
value = []               // OK
value = {}               // OK
value = Math.random      // OK
value = null             // OK
value = undefined        // OK
value = new TypeError()  // OK
value = Symbol('name')   // OK

所有對該 value 變量的分配都被認爲是類型正確的。

但是,如果嘗試:

let value: unknown

let value1: unknown = value   // OK
let value2: any = value       // OK

let value3: boolean = value   // Error
let value4: number = value    // Error
let value5: string = value    // Error
let value6: object = value    // Error
let value7: any[] = value     // Error

可以看到,該 unknown 類型只能分配給 any 類型和 unknown 類型本身。

現在繼續嘗試:

let value: unknown

value.foo.bar  // Error
value.trim()   // Error
value()        // Error
new value()    // Error
value[0][1]    // Error

unknown 類型在被確定爲某個類型之前,不能被進行諸如函數執行、實例化等操作,一定程度上對類型進行了保護。

在那些將取得任意值,但不知道具體類型的地方使用 unknown,而非 any

4. 小結

到本節爲止我們介紹了 TypeScript 的各種基本類型。

TypeScript 的類型系統會對數據進行類型檢查,它可以在編譯階段規避不必要的錯誤,並且語義化清晰,有助於代碼的閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章