TypeScript Never 與 Unknown
本節(jié)介紹 never 和 unknown 類型,其中 unknown 類型作為 any 類型對應(yīng)的安全類型使用起來更加安全,如果有 any 類型的使用需求,應(yīng)盡量使用 unknown 類型來替代 any 類型。
1. 慕課解釋
never
類型表示那些永不存在的值的類型。
unknown
類型是 any
類型對應(yīng)的安全類型。
2. never 類型
never 類型是任何類型的子類型,也可以賦值給任何類型;然而,沒有類型是 never 的子類型或可以賦值給 never 類型(除了 never 本身之外)。 即使 any 也不可以賦值給 never。
2.1 應(yīng)用場景
一個拋出異常的函數(shù)表達式,其函數(shù)返回值類型為 never:
function error(message:string): never {
throw new Error(message)
}
同樣的,不會有返回值的函數(shù)表達式,其函數(shù)返回值類型也為 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)、聯(lián)合類型(A | B)之后都有專門小節(jié)介紹。
3. unknown 類型
我們知道 any 無需事先執(zhí)行任何類型的檢查:
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
變量的分配都被認(rèn)為是類型正確的。
但是,如果嘗試:
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 類型本身。
現(xiàn)在繼續(xù)嘗試:
let value: unknown
value.foo.bar // Error
value.trim() // Error
value() // Error
new value() // Error
value[0][1] // Error
unknown
類型在被確定為某個類型之前,不能被進行諸如函數(shù)執(zhí)行、實例化等操作,一定程度上對類型進行了保護。
在那些將取得任意值,但不知道具體類型的地方使用
unknown
,而非any
。
4. 小結(jié)
到本節(jié)為止我們介紹了 TypeScript 的各種基本類型。
TypeScript 的類型系統(tǒng)會對數(shù)據(jù)進行類型檢查,它可以在編譯階段規(guī)避不必要的錯誤,并且語義化清晰,有助于代碼的閱讀。