一個變數如果聲明為聯合類型,而後續操作需要針對其具體的單一類型做不同處理,這個過程就叫做類型收窄(`Narrowing`) ...
TS官方手冊:TypeScript: Handbook - The TypeScript Handbook (typescriptlang.org)
一個變數如果聲明為聯合類型,而後續操作需要針對其具體的單一類型做不同處理,這個過程就叫做類型收窄(Narrowing
)。
常見的做法或情形有以下:
typeof 類型保護(type guards)
typeof
是 JS 中的操作符,需要註意typeof
對象、數組、null
都會返回object
。
真值收窄(Truthiness narrowing)
0
,NaN
,""
,0n
,null
,undefined
都會被隱式轉換為false
,屬於假值,其它的值是真值。依據這個規則也可以收窄類型。
等值收窄(Equality narrowing)
在 JS 中,全等判斷符===
要求兩邊類型一致,以此也可以排除一些類型,從而實現收窄類型。
in 操作符收窄
in操作符檢查指定的屬性是否在指定的對象或其原型鏈中。
instanceof 收窄
instanceof
運算符用於檢測構造函數的 prototype
屬性是否出現在某個實例對象的原型鏈上。
賦值語句(Assignments)
TS 可以根據賦值語句的右值的類型收窄左值。
![image-20231127221150198](https://fox-blog-image-1312870245.cos.ap-guangzhou.myqcloud.com/202311272211409.png)
控制流分析(Control flow analysis)
基於可達性的代碼分析就是控制流分析,關註代碼中的if
,while
等條件控制語句。
如果代碼達到了某個區域,而根據條件控制語句可以得知:如果變數X是類型A,無法到達此區域,那麼就可以推斷出到達此區域的變數X的類型不可能是A。
於是類型收窄。
function padLeft(padding: number | string, input: string) {
if (typeof padding === "number") {
return new Array(padding + 1).join(" ") + input;
}
return padding + input;
}
在第一個 if
語句里,因為有 return
語句,TypeScript 就能通過代碼分析,判斷出在剩餘的部分 return padding + input
,如果 padding 是 number
類型,是無法達到 (unreachable) 這裡的,所以在剩餘的部分,就會將 number
類型從 number | string
類型中刪除掉。