"I'm trying to find a way to pass an object to function in and check it type in a runtime".
Since a class instance is just an object
, the "native" answer is to use a class instance and instanceof
when runtime type checking is needed, use an interface when not in order to keep a contract and decouple your application, make reduce signature size on methods/ctors, while not add any additional size. In my humble opinion this is one of a few main considerations for me in TypeScript when deciding to use a class vs type/interface. One other main driving factor is whether the object will ever need to be instantiated vs if it for instance defines a POJO.
In my codebase, I will typically have a class which implements an interface and the interface is used during compilation for pre-compile time type safety, while classes are used to organize my code and allow for ease in passing data between functions, classes and method as well as do runtime type checks in typescript.
Works because routerEvent is an instance of NavigationStart class
if (routerEvent instanceof NavigationStart) {
this.loading = true;
}
if (routerEvent instanceof NavigationEnd ||
routerEvent instanceof NavigationCancel ||
routerEvent instanceof NavigationError) {
this.loading = false;
}
Will not work
// Must use a class not an interface
export interface IRouterEvent { ... }
// Fails
expect(IRouterEvent instanceof NavigationCancel).toBe(true);
Will not work
// Must use a class not a type
export type RouterEvent { ... }
// Fails
expect(IRouterEvent instanceof NavigationCancel).toBe(true);
As you can see by the code above, classes are used to compare the instance to the types NavigationStart|Cancel|Error
within the Angular library and if you have used the router before you a project I am willing to be that you have done similar if not identical checks within your own codebase in order to determine application state during runtime.
Using instanceof
on a Type or Interface is not possible, since the ts compiler strips away these attributes during its compilation process and prior to being interpreted by JIT or AOT. Classes are a great way to create a type which can be used pre-compilation as well as during the JS runtime.
Update 2022
In addition to my original response to this, you can leverage The TypeScript Reflect Metadata API or roll your own solution using the TypeScript compiler to do static analysis of your code and parse the AST, querying like so:
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
// ...
break;
case ts.SyntaxKind.TypeDeclaration:
// ...
break;
}
See this solution for additonal details