在 TypeScript 中檢查執行時的物件型別
本文討論如何在 TypeScript 執行時檢查物件型別。
TypeScript 中的主要型別
TypeScript 是一種強型別語言。因此,它會在編譯時檢查型別,從而減少執行時錯誤。
在 TypeScript 中,我們有幾種主要型別,如下所示。
- 原始型別,例如字串、數字和布林值
- 自定義類型別
- 介面型別
- 工會型別
- 輸入別名
在 TypeScript 中檢查執行時的類型別
TypeScript 支援 EcmaScript 6 中的 class
關鍵字。它可用於以 OOP 方式編寫程式碼。
讓我們建立類 Engineer
。
class Engineer {
}
讓我們新增一個方法,因為此類不包含任何屬性或行為。
class Engineer {
visitSite(): void {
console.log("This is the Engineer class");
}
}
假設我們有另一個類 Doctor
,如下所示。
class Doctor {
visitWard(): void {
console.log("This is the Doctor class");
}
}
Engineer
和 Doctor
是兩種使用者定義的型別。在某些情況下,我們必須檢查現有物件型別是否屬於 Engineer
或 Doctor
類。
這對於 TypeScript instanceof
運算子來說非常簡單。
使用 instanceof
運算子檢查類型別
它檢查給定物件是 TypeScript 類的例項還是建構函式。它考慮多級繼承來檢查相關類是否出現在不同的級別。
如果找到匹配的類,它將返回 true
;否則,它將輸出 false
。
語法:
my_object instanceof my_custom_class_type
讓我們使用這個運算子來區分 TypeScript 邏輯中的 Engineer
和 Doctor
類。
首先,我們將建立一個新的檢查函式 checkObjectType()
。
function checkObjectType(myObject) {
if (myObject instanceof Engineer) {
myObject.visitSite()
}
if (myObject instanceof Doctor) {
myObject.visitWard()
}
}
在上面的檢查器函式中,我們檢查了 myObject
的類。根據結果,我們將所屬的類方法稱為 visitSite()
或 visitWard()
。
讓我們從兩個類中啟動物件並將物件傳遞給 checkObjectType
方法。
let engineerObject: Engineer = new Engineer;
let doctorObject: Doctor = new Doctor;
checkObjectType(engineerObject);
checkObjectType(doctorObject);
輸出:
正如預期的那樣,TypeScript 為提供的每個物件識別正確的類。
在 TypeScript 中檢查執行時的介面型別
instanceof
可用於檢查給定例項是否屬於某個類。但是,這不適用於 TypeScript 介面型別或型別別名。
在執行時,所有這些介面型別都消失了。因此,通常的 JavaScript typeof
運算子將輸出作為 object
。
讓我們定義兩個介面,Airplane
和 Car
,如下所示。
interface Airplane {
hasWings() {
console.log("2 wings");
}
}
interface Car {
hasWheels() {
console.log("4 wheels");
}
}
接下來,我們將建立一個 TypeScript 使用者定義的型別保護來檢查給定的物件是屬於 Airplane
還是 Car
型別,並將物件縮小為相容的型別。在這裡,我們應該使用型別謂詞作為返回型別。
型別謂詞的語法:
my_parameter_name is custom_type
my_parameter_name
應該是傳遞給函式的當前引數。在這種情況下,custom_type
將是 Airplane
或 Car
。
讓我們來定義這兩個型別的守護。
function isAirplane(anyObject: any): anyObject is Airplane {
return (anyObject as Airplane).hasWings() !=== undefined;
}
我們通過檢查 hasWings()
方法是否可用於傳遞的物件 anyObject
來檢查物件的形狀是否等同於介面形狀。然後,我們返回將物件縮小為 Airplane
型別的型別謂詞。
我們可以類似地實現 isCar()
函式。
function isCar(anyObject: any): anyObject is Car {
return (anyObject as Car).hasWheels() !=== undefined;
}
最後,我們可以實現 testType()
函式來測試程式碼。
let car: Car = {wheels: 4};
let flight: Airplane = {wings: 2};
function testType(obj: any) {
if (isAirplane(obj)) {
// 'obj' is narrowed to type 'Airplane'
console.log("Airplane wings: "+ obj.wings);
}
else if (isCar(obj)) {
// 'obj' is narrowed to type 'Car'
console.log("Car wheels: "+ obj.wheels);
}
}
testType(car);
testType(flight);
輸出:
藉助使用者定義的型別保護,我們可以在執行時檢查介面的確切型別。
Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.