Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if an object implements an interface at runtime with TypeScript

I load a JSON configuration file at runtime, and use an interface to define its expected structure:

interface EngineConfig {     pathplanner?: PathPlannerConfig;     debug?: DebugConfig;     ... }  interface PathPlannerConfig {     nbMaxIter?: number;     nbIterPerChunk?: number;     heuristic?: string; }  interface DebugConfig {     logLevel?: number; }  ... 

This makes it convenient to access the various properties since I can use autocompletions etc.

Question: is there a way to use this declaration to check the correctness of the file I load? ie that I do not have unexpected properties?

like image 973
MasterScrat Avatar asked Nov 19 '15 09:11

MasterScrat


People also ask

Does TypeScript check types at runtime?

By default, TypeScript does not verify types at runtime in order to avoid runtime overhead and aggressively optimize runtime performance as a part of its design goals.

How do you know if a class implements an interface?

To declare a class that implements an interface, you include an implements clause in the class declaration. Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class.

Is interface an object TypeScript?

Using this information, TypeScript creates an implicit interface type for student . An interface is just like an object but it only contains the information about object properties and their types.

How do you check if an object is an instance of an interface?

Use a user-defined type guard to check if an object implements an interface in TypeScript. The user-defined type guard consists of a function, which checks if the passed in object contains specific properties and returns a type predicate.


1 Answers

There "is" a way, but you have to implement it yourself. It's called a "User Defined Type Guard" and it looks like this:

interface Test {     prop: number; }  function isTest(arg: any): arg is Test {     return arg && arg.prop && typeof(arg.prop) == 'number'; } 

Of course, the actual implementation of the isTest function is totally up to you, but the good part is that it's an actual function, which means it's testable.

Now at runtime you would use isTest() to validate if an object respects an interface. At compile time typescript picks up on the guard and treats subsequent usage as expected, i.e.:

let a:any = { prop: 5 };  a.x; //ok because here a is of type any  if (isTest(a)) {     a.x; //error because here a is of type Test } 

More in-depth explanations here: https://basarat.gitbook.io/typescript/type-system/typeguard

like image 184
Teodor Sandu Avatar answered Sep 27 '22 00:09

Teodor Sandu