TypeScript 類型保護(hù)
本節(jié)介紹的類型保護(hù) TypeScript 類型檢查機(jī)制的第二個(gè)部分,我們可以通過(guò) typeof
、instanceof
、in
和 字面量類型
將代碼分割成范圍更小的代碼塊,在這一小塊中,變量的類型是確定的。
1. 慕課解釋
類型保護(hù)是指縮小類型的范圍,在一定的塊級(jí)作用域內(nèi)由編譯器推導(dǎo)其類型,提示并規(guī)避不合法的操作。
2. typeof
通過(guò) typeof
運(yùn)算符判斷變量類型,下面看一個(gè)之前介紹函數(shù)重載時(shí)的例子:
function reverse(target: string | number) {
if (typeof target === 'string') {
target.toFixed(2) // Error,在這個(gè)代碼塊中,target 是 string 類型,沒(méi)有 toFixed 方法
return target.split('').reverse().join('')
}
if (typeof target === 'number') {
target.toFixed(2) // OK
return +[...target.toString()].reverse().join('')
}
target.forEach(element => {}) // Error,在這個(gè)代碼塊中,target 是 string 或 number 類型,沒(méi)有 forEach 方法
}
代碼解釋:
第 2 行,通過(guò) typeof 關(guān)鍵字,將這個(gè)代碼塊中變量 target 的類型限定為 string 類型。
第 6 行,通過(guò) typeof 關(guān)鍵字,將這個(gè)代碼塊中變量 target 的類型限定為 number 類型。
第 11 行,因沒(méi)有限定,在這個(gè)代碼塊中,變量 target 是 string 或 number 類型,沒(méi)有 forEach 方法,所以報(bào)錯(cuò)。
3. instanceof
instanceof 與 typeof 類似,區(qū)別在于 typeof 判斷基礎(chǔ)類型,instanceof 判斷是否為某個(gè)對(duì)象的實(shí)例:
class User {
public nickname: string | undefined
public group: number | undefined
}
class Log {
public count: number = 10
public keyword: string | undefined
}
function typeGuard(arg: User | Log) {
if (arg instanceof User) {
arg.count = 15 // Error, User 類型無(wú)此屬性
}
if (arg instanceof Log) {
arg.count = 15 // OK
}
}
代碼解釋:
第 12 行,通過(guò) instanceof 關(guān)鍵字,將這個(gè)代碼塊中變量 arg 的類型限定為 User 類型。
第 16 行,通過(guò) instanceof 關(guān)鍵字,將這個(gè)代碼塊中變量 arg 的類型限定為 Log 類型。
4. in
in
操作符用于確定屬性是否存在于某個(gè)對(duì)象上,這也是一種縮小范圍的類型保護(hù)。
class User {
public nickname: string | undefined
public groups!: number[]
}
class Log {
public count: number = 10
public keyword: string | undefined
}
function typeGuard(arg: User | Log) {
if ('nickname' in arg) {
// (parameter) arg: User,編輯器將推斷在當(dāng)前塊作用域 arg 為 User 類型
arg.nickname = 'imooc'
}
if ('count' in arg) {
// (parameter) arg: Log,編輯器將推斷在當(dāng)前塊作用域 arg 為 Log 類型
arg.count = 15
}
}
代碼解釋:
第 12 行,通過(guò) in 關(guān)鍵字,將這個(gè)代碼塊中變量 arg 的類型限定為 User 類型。
第 17 行,通過(guò) in 關(guān)鍵字,將這個(gè)代碼塊中變量 arg 的類型限定為 Log 類型。
5. 字面量類型保護(hù)
用字面量類型那一節(jié)的例子改造一下來(lái)介紹字面量類型保護(hù):
type Success = {
success: true,
code: number,
object: object
}
type Fail = {
success: false,
code: number,
errMsg: string,
request: string
}
function test(arg: Success | Fail) {
if (arg.success === true) {
console.log(arg.object) // OK
console.log(arg.errMsg) // Error, Property 'errMsg' does not exist on type 'Success'
} else {
console.log(arg.errMsg) // OK
console.log(arg.object) // Error, Property 'object' does not exist on type 'Fail'
}
}
代碼解釋:
第 15 行,通過(guò)布爾字面量,將這個(gè)代碼塊中變量 arg 的類型限定為 Success 類型。
第 18 行,通過(guò)布爾字面量,將這個(gè)代碼塊中變量 arg 的類型限定為 Fail 類型。
6. 小結(jié)
類型保護(hù)就是讓編譯器幫助我們縮小類型范圍,在編譯階段規(guī)避掉一些不必要的錯(cuò)誤,提高代碼質(zhì)量。