Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface type check with Typescript

This question is the direct analogon to Class type check with TypeScript

I need to find out at runtime if a variable of type any implements an interface. Here's my code:

interface A{     member:string; }  var a:any={member:"foobar"};  if(a instanceof A) alert(a.member); 

If you enter this code in the typescript playground, the last line will be marked as an error, "The name A does not exist in the current scope". But that isn't true, the name does exist in the current scope. I can even change the variable declaration to var a:A={member:"foobar"}; without complaints from the editor. After browsing the web and finding the other question on SO I changed the interface to a class but then I can't use object literals to create instances.

I wondered how the type A could vanish like that but a look at the generated javascript explains the problem:

var a = {     member: "foobar" }; if(a instanceof A) {     alert(a.member); } 

There is no representation of A as an interface, therefore no runtime type checks are possible.

I understand that javascript as a dynamic language has no concept of interfaces. Is there any way to type check for interfaces?

The typescript playground's autocompletion reveals that typescript even offers a method implements. How can I use it ?

like image 274
lhk Avatar asked Jan 20 '13 14:01

lhk


People also ask

How TypeScript check types?

Using TypeScript type guards Checking a specific value's type at runtime is the primary function of type guards. This helps the TypeScript compiler, which then uses the information to become more predictive about the types. The above code snippet showcases the example of the type guard instanceof .

Is type of interface TypeScript?

TypeScript Interface TypeTypeScript allows you to specifically type an object using an interface that can be reused by multiple objects. To create an interface, use the interface keyword followed by the interface name and the typed object.

Does TypeScript check types at runtime?

TypeScript only performs static type checking at compile time! The generated JavaScript, which is what actually runs when you run your code, does not know anything about the types.


2 Answers

You can achieve what you want without the instanceof keyword as you can write custom type guards now:

interface A{     member:string; }  function instanceOfA(object: any): object is A {     return 'member' in object; }  var a:any={member:"foobar"};  if (instanceOfA(a)) {     alert(a.member); } 

Lots of Members

If you need to check a lot of members to determine whether an object matches your type, you could instead add a discriminator. The below is the most basic example, and requires you to manage your own discriminators... you'd need to get deeper into the patterns to ensure you avoid duplicate discriminators.

interface A{     discriminator: 'I-AM-A';     member:string; }  function instanceOfA(object: any): object is A {     return object.discriminator === 'I-AM-A'; }  var a:any = {discriminator: 'I-AM-A', member:"foobar"};  if (instanceOfA(a)) {     alert(a.member); } 
like image 91
Fenton Avatar answered Sep 17 '22 18:09

Fenton


In TypeScript 1.6, user-defined type guard will do the job.

interface Foo {     fooProperty: string; }  interface Bar {     barProperty: string; }  function isFoo(object: any): object is Foo {     return 'fooProperty' in object; }  let object: Foo | Bar;  if (isFoo(object)) {     // `object` has type `Foo`.     object.fooProperty; } else {     // `object` has type `Bar`.     object.barProperty; } 

And just as Joe Yang mentioned: since TypeScript 2.0, you can even take the advantage of tagged union type.

interface Foo {     type: 'foo';     fooProperty: string; }  interface Bar {     type: 'bar';     barProperty: number; }  let object: Foo | Bar;  // You will see errors if `strictNullChecks` is enabled. if (object.type === 'foo') {     // object has type `Foo`.     object.fooProperty; } else {     // object has type `Bar`.     object.barProperty; } 

And it works with switch too.

like image 45
vilicvane Avatar answered Sep 20 '22 18:09

vilicvane