如何转换为对象可能实现的接口?

时间:2014-04-25 00:02:57

标签: interface typescript

我有以下课程&接口:

export interface IBody {
    body : ListBody;
}

export class Element  {
// ...
}

export class Paragraph extends Element implements IBody {
// ...
}

export class Character extends Element {
// ...
}

我有代码,我将得到一个Element派生对象数组(不仅仅是Paragraph& Character)。对于那些实现IBody的人,我需要对身体中的元素采取行动。

查看它是否实现IBody的最佳方法是什么?是“if(element.body!== undefined)”?

然后我如何访问它? “var bodyElement =< IBody> element;”给我一个错误。

C:/src/jenova/Dev/Merge/AutoTagWeb/client/layout/document/elements/factory.ts(34,27): error TS2012: Cannot convert 'Element' to 'IBody':
    Type 'Element' is missing property 'body' from type 'IBody'.
    Type 'IBody' is missing property 'type' from type 'Element'.

谢谢 - 戴夫

1 个答案:

答案 0 :(得分:25)

TypeScript中的interface是仅编译时构造,没有运行时表示。您可能会发现TypeScript规范的第7部分很有趣,因为它具有完整的详细信息。

所以,你不能测试"特别是interface。正确而完整地完成后,您通常不需要对其进行测试,因为编译器应该已经捕获了对象没有实现必要接口的情况。如果您尝试使用类型断言:

// // where e has been typed as any, not an Element
var body = <IBody> e; 

编译器会在没有警告的情况下允许它,因为您已断言类型为IBody。但是,如果e在范围内是Element,则您显示的编译器将检查Element的签名并确认它具有IBody声明的属性/方法。 {1}}。重要的是要注意它检查签名 - 只要签名匹配,它就不会实现IBody并不重要。

假设Element具有与IBody匹配的签名,它将起作用。如果没有,您将收到您正在接收的编译器错误。但是,再次,如果它被声明为any,则断言将在运行时传递,除非该类型具有在IBody上定义的方法,否则脚本将失败。

由于您的Element是基类,因此无法检查IBody。您可以将参数声明为any

function someFeature(e: any) {

} 

然后断言IBody存在:

function someFeature(e: any) {
     var body :IBody = <IBody> e;    
     // do something
} 

但是,如果您确实需要运行时检查,则需要在使用prototype或作为属性之前查找该功能。虽然在某些情况下这可能会产生误导,但TypeScript中的interface也可能没有发现不匹配。 Here是一个如何检查特定函数是否存在的示例。

可能看起来像这样:

function someFeature(e: any) {
    var body = <IBody> e;
    if (typeof (body.someFunctionOnBodyInterface) === "undefined") {
        // not safe to use the function
        throw new Error("Yikes!");
    }

    body.someFunctionOnBodyInterface();
}