如何转换为对象可能实现的接口? [英] How do I cast to an interface an object may implement?

查看:148
本文介绍了如何转换为对象可能实现的接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程&接口:

I have the following classes & interfaces:

export interface IBody {
    body : ListBody;
}

export class Element  {
// ...
}

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

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

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

I have code where I will get an array of Element derived objects (there are more than just Paragraph & Character). In the case of those that implement IBody, I need to take action on the elements in the body.

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

What is the best way to see if it implements IBody? Is it "if (element.body !== undefined)"?

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

And then how do I access it? "var bodyElement = <IBody> element;" gives me an error.

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'.

谢谢 - 戴夫

推荐答案

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

An interface in TypeScript is a compile-time only construct, with no run-time representation. You might find section 7 of the TypeScript specification interesting to read as it has the complete details.

因此,您无法测试 interface 具体来说。正确完整地完成后,通常不需要测试它,因为编译器应该已经捕获了对象没有实现必要接口的情况。如果你尝试使用类型断言:

So, you can't "test" for an interface specifically. Done correctly and completely, you generally shouldn't need to test for it as the compiler should have caught the cases where an object didn't implement the necessary interface. If you were to try using a type assertion:

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

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

The compiler will allow it without warning as you've asserted that the type is an IBody. If however, e were an Element in scope, the compiler as you've shown will check the signature of the Element and confirm that it has the properties/methods declared by IBody. It's important to note that it's checking the signature -- it doesn't matter that it may not implement IBody as long as the signature matches up.

假设元素的签名符合 IBody ,它会工作。如果没有,您将收到您收到的编译器错误。但是,再次,如果它被声明为任何,断言将在运行时传递,除非该类型具有在 IBody上定义的方法,脚本将失败。

Assuming that Element has a signature that matches IBody, it will work. If it does not, you'll get the compiler error you're receiving. But, again, if it's declared as any, the assertion will pass and at run-time, unless the type has the methods defined on IBody, the script will fail.

由于你的元素是基类,你无法检查 IBody 。您可以将参数声明为任何

As your Element is the base class, you cannot check for IBody. You could declare an argument as any:

function someFeature(e: any) {

} 

然后断言 IBody 存在:

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

但是,如果你确实需要跑步 - 时间检查,您需要在使用它之前在原型上查找该函数或作为属性。虽然在某些情况下这可能会产生误导,但TypeScript中的接口也可能没有捕获到不匹配。 此处是如何检查特定功能是否存在的示例。

However, if you do need a run-time check, you'd need to look for the function on the prototype or as a property before using it. While that could be misleading in some cases, the interface in TypeScript also may not have caught the mismatch either. Here's an example of how you could check for the existence of a specific function.

它可能如下所示:

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

这篇关于如何转换为对象可能实现的接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆