在 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.