使用Typescript检查接口types

这个问题是TypeScripttypes检查的直接模拟

我需要在运行时找出任何types的variables是否实现了一个接口。 这是我的代码:

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

如果您在打字稿中input此代码,则最后一行将被标记为“名称A在当前范围内不存在”的错误。 但事实并非如此,这个名字在目前的范围内确实存在。 我甚至可以将variables声明更改为var a:A={member:"foobar"}; 没有编辑的投诉。 在浏览网页并find其他问题后,我将接口更改为一个类,但是不能使用对象字面值来创build实例。

我想知道如何typesA可以消失,但看看生成的JavaScript解释了这个问题:

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

没有将A表示为接口,因此不可能进行运行时types检查。

我明白,JavaScript作为一种dynamic语言没有接口的概念。 有没有什么办法来检查接口?

打字游戏的自动完成显示打字稿甚至提供了一个方法implements 。 我怎样才能使用它?

你可以在没有instanceof关键字的instanceof实现你想要的function,因为你现在可以编写自定义的types守卫:

 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); } 

在TypeScript 1.6中, 用户定义的types后卫将完成这项工作。

 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; } 

正如Joe Yang所说:自TypeScript 2.0以来,您甚至可以利用标记的联合types。

 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; } 

它也适用于switch

打字稿2.0介绍标记的联盟

Typescript 2.0function

 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; } } 

用户定义的types守卫怎么样? https://www.typescriptlang.org/docs/handbook/advanced-types.html

 interface Bird { fly(); layEggs(); } interface Fish { swim(); layEggs(); } function isFish(pet: Fish | Bird): pet is Fish { //magic happens here return (<Fish>pet).swim !== undefined; } // Both calls to 'swim' and 'fly' are now okay. if (isFish(pet)) { pet.swim(); } else { pet.fly(); } 

现在有可能,我刚刚发布了一个提供全面reflectionfunction的TypeScript编译器的增强版本。 您可以从它们的元数据对象实例化类,从类构造器中检索元数据,并在运行时检查接口/类。 你可以在这里查看

用法示例:

在其中一个打字稿文件中,创build一个接口和一个实现它的类,如下所示:

 interface MyInterface { doSomething(what: string): number; } class MyClass implements MyInterface { counter = 0; doSomething(what: string): number { console.log('Doing ' + what); return this.counter++; } } 

现在让我们打印一些实现的接口列表。

 for (let classInterface of MyClass.getClass().implements) { console.log('Implemented interface: ' + classInterface.name) } 

用反思编译并启动它:

 $ node main.js Implemented interface: MyInterface Member name: counter - member kind: number Member name: doSomething - member kind: function 

有关Interface元types的详细信息,请参阅reflection.d.ts。

更新:你可以在这里find一个完整的工作示例

我想指出,TypeScript不提供一个直接的机制来dynamictesting一个对象是否实现了一个特定的接口。

相反,TypeScript代码可以使用JavaScript技术来检查对象上是否存在适当的成员集合。 例如:

 var obj : any = new Foo(); if (obj.someInterfaceMethod) { ... } 

TypeGuards

 interface MyInterfaced { x: number } function isMyInterfaced(arg: any): arg is MyInterfaced { return arg.x !== undefined; } if (isMyInterfaced(obj)) { (obj as MyInterfaced ).x; }