Check if an object implements an interface at runtime with TypeScript
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
Here is another alternative, specifically for this:
ts-interface-builder is a tool you run at build time on your TypeScript file (e.g. foo.ts
) to build runtime descriptors (e.g. foo-ti.ts
).
ts-interface-checker uses these to validate objects at runtime. E.g.
import {createCheckers} from 'ts-interface-checker';
import fooDesc from 'foo-ti.ts';
const checkers = createCheckers(fooDesc);
checkers.EngineConfig.check(someObject); // Succeeds or throws an informative error
checkers.PathPlannerConfig.check(someObject);
You can use strictCheck()
method to ensure there are no unknown properties.