Interface type check with Typescript
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);}
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.
typescript 2.0 introduce tagged union
interface Square { kind: "square"; size: number;}interface Rectangle { kind: "rectangle"; width: number; height: number;}interface Circle { kind: "circle"; radius: number;}type Shape = Square | Rectangle | Circle;function area(s: Shape) { // In the following switch statement, the type of s is narrowed in each case clause // according to the value of the discriminant property, thus allowing the other properties // of that variant to be accessed without a type assertion. switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; }}