[英]How to check the type of an object in TypeScript when it has multiple return type?
我有一個具有多個返回類型的方法。 在這里,一種類型是數組,其余都是單個 object。我想檢查返回類型是否為數組,然后使用循環,否則不使用。
我可以通過使用as
來檢測數組類型,但是當我添加if..else
條件時,我得到// Getting Property 'forEach' does not exist on type 'output1Model | output2Model | output3Model[]'. Property 'forEach' does not exist on type 'output1Model'.
// Getting Property 'forEach' does not exist on type 'output1Model | output2Model | output3Model[]'. Property 'forEach' does not exist on type 'output1Model'.
錯誤。
為什么它以output1Model
為目標,即使返回類型指示所有三個?
代碼:
服務.ts
myFunction(input: someModel): output1Model | output2Model | output3Model[] {
// Some logic.
// Return type would be either of these 3 based on condition.
}
controller.ts
const checkThis = Service.myFunction(input);
// ERROR: Getting Property 'forEach' does not exist on type 'output1Model | output2Model | output3Model[]'.
// Property 'forEach' does not exist on type 'output1Model'.
if (checkThis as output3Model[]) {
checkThis.forEach(element => {
// DO SOMETHING
});
} else {
// DO SOMETHING
}
這里有一些誤解:
checkThis as output3Model[]
沒有檢測checkThis
是否是一個output3Model[]
,它斷言它是一個。 換句話說:您是在告訴編譯器,而不是詢問它。
類型斷言僅影響它們在其中使用的表達式,不會傳播到斷言變量的后續使用。 因此,雖然您可以編寫(checkThis as output3Model[]).forEach(...)
來縮小checkThis
的感知類型,以便編譯器不會抱怨,但您不能編寫(checkThis as output3Model[])
然后稍后再checkThis.forEach()
。 checkThis
的第二次使用不是縮小。 如果你想要“檢查並堅持”行為,你需要使用控制流分析。 否則,您必須在每次使用checkThis
時都斷言。
類型斷言只是與編譯器就您期望看到的類型進行通信的一種方式。 它是 static 類型系統的一部分,因此從發出的 JavaScript 中刪除。上面的代碼最終在 JavaScript 中運行,如下所示:
if (checkThis) { checkThis.forEach(element => { // DO SOMETHING }); }
因此,您可以看到您為“檢測” checkThis
的類型所做的一切都是為了確保它不是falsy 。 大概output1Model
和output2Model
是一些對象,因此不是假的,所以這個檢查將始終嘗試運行checkThis.forEach()
即使checkThis
沒有forEach()
方法。 您需要運行時檢查,而不是類型系統工件。
所有這一切都意味着編譯器將checkThis
視為原始類型output1Model | output2Model | output3Model[]
output1Model | output2Model | output3Model[]
output1Model | output2Model | output3Model[]
,它抱怨說因為它不確定它有一個forEach()
方法,所以嘗試調用它是不安全的。
答案“為什么它以output1Model
為目標,即使返回類型指示所有三個?” 與 TypeScript 中錯誤消息的生成方式有關。 如果你有一個類型為A | B | C | D | E | F
的值v
A | B | C | D | E | F
A | B | C | D | E | F
並且您嘗試以僅適用於A
的方式使用它,編譯器可能會生成一個包含五個錯誤消息的列表,例如“ v
可能是一個B
,如果是這樣,您將無法執行您正在做的事情。 “ 和“或者v
可能是C
,如果是這樣,你就不能做你正在做的事情。” 等等直到“最后, v
可能是F
,如果是這樣,你就不能做你正在做的事情”。 但實際上,這些錯誤消息中的任何一條都足以告訴您您犯了一個錯誤。 所以它只選擇它遇到的第一個。 v
可能是B
的事實足以產生關於為什么B
不讓你做你想做的事情的警告。
總而言之,您需要使用編譯器可以分析的運行時檢查來驗證您是否將checkThis
一個數組,只有當它肯定是一個數組時。 有幾種方法可以做到這一點。
我的建議是Array.isArray()
,其TypeScript 中的類型簽名是類型保護 function的類型簽名。 如果Array.isArray(checkThis)
在運行時返回true
,那么編譯器知道在控制流中對checkThis
的任何后續使用都可以被視為一個數組,因此是一個output3Model[]
。 如果它返回false
,那么編譯器就知道它不是一個數組,因此必須是一個output1Model | output2Model
output1Model | output2Model
(假設那些不是數組類型):
if (Array.isArray(checkThis)) {
checkThis.forEach(element => {
// (parameter) element: output3Model
});
} else {
checkThis
// const checkThis: output1Model | output2Model
}
我打賭你應該確保你的checkThis
是另一種方式的數組,像這樣:
if (Array.isArray(checkThis)) {
checkThis.forEach(element => {
// DO SOMETHING
});
} else {
// DO SOMETHING
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.