我正在尝试找到一种方法,在运行时将一个对象传递给函数并检查它的类型。由于类实例只是一个“对象”,因此使用类实例和instanceof在需要运行时类型检查时使用“本机”答案,使用接口而不是为了保持合同并解耦您的应用程序,减少方法/构造函数的签名大小,同时不添加任何额外的大小。在我看来,这是在TypeScript中决定使用类与类型/接口之间考虑的几个主要因素之一。另一个主要驱动因素是对象是否需要被实例化,例如是否定义了POJO。
在我的代码库中,我通常会有一个实现接口的类,并且接口在编译期间用于预编译时间类型安全性,而类则用于组织我的代码,并允许在TypeScript中在函数、类和方法之间传递数据以及进行运行时类型检查。
这起作用是因为routerEvent是NavigationStart类的一个实例
if (routerEvent instanceof NavigationStart) {
this.loading = true;
}
if (routerEvent instanceof NavigationEnd ||
routerEvent instanceof NavigationCancel ||
routerEvent instanceof NavigationError) {
this.loading = false;
}
无法正常工作
export interface IRouterEvent { ... }
expect(IRouterEvent instanceof NavigationCancel).toBe(true);
无法运行
export type RouterEvent { ... }
expect(IRouterEvent instanceof NavigationCancel).toBe(true);
正如您在上面的代码中所看到的,类用于将实例与Angular库中的
NavigationStart|Cancel|Error
类型进行比较。如果您之前使用过路由器,在运行时检查应用程序状态时,很可能在自己的代码库中执行了类似甚至相同的检查。
使用
instanceof
来检查类型或接口是不可能的,因为ts编译器在其编译过程中会剥离这些属性,在被JIT或AOT解释之前。类是一种很好的方式,可以在预编译期间以及在JS运行时期间创建一个类型。
2022年更新
除了我最初对此的回答外,您还可以利用
TypeScript反射元数据API或使用TypeScript编译器自行解决方案,对代码进行静态分析并解析AST,进行查询,如下所示:
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
break;
case ts.SyntaxKind.TypeDeclaration:
break;
}
请参考
此解决方案获取更多详细信息。
instanceof
不起作用,所以我猜他有一个非类实例对象。 - Aaron Beallif (isA(obj)): obj is A { ... }
? - 55 Cancri