typescript 如何转换为对象可能实现的接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23281962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I cast to an interface an object may implement?
提问by David Thielen
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 {
// ...
}
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 的情况,我需要对 body 中的元素采取行动。
What is the best way to see if it implements IBody? Is it "if (element.body !== undefined)"?
查看它是否实现 IBody 的最佳方法是什么?是“if (element.body !== undefined)”吗?
And then how do I access it? "var bodyElement = <IBody> element;" gives me an error.
然后我如何访问它?“var bodyElement = <IBody> 元素;” 给我一个错误。
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'.
thanks - dave
谢谢 - 戴夫
回答by WiredPrairie
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
TypeScript 中的An是仅编译时构造,没有运行时表示。您可能会发现 TypeScript 规范的第 7 节很有趣,因为它具有完整的详细信息。
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:
所以,你不能interface
专门“测试” 。如果正确且完整地完成,您通常不需要对其进行测试,因为编译器应该已经发现对象没有实现必要接口的情况。如果您要尝试使用类型断言:
// // where e has been typed as any, not an Element
var body = <IBody> e;
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
. 但是,如果e
是Element
in 范围,则如您所示,编译器将检查 的签名Element
并确认它具有由 声明的属性/方法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.
假设Element
具有匹配的签名,IBody
它将起作用。如果没有,您将收到您收到的编译器错误。但是,同样,如果它被声明为any
,则断言将通过,并且在运行时,除非该类型具有在 上定义的方法,否则IBody
脚本将失败。
As your Element
is the base class, you cannotcheck for IBody
. You could declare an argument as any
:
由于您Element
是基类,因此您无法检查IBody
. 您可以将参数声明为any
:
function someFeature(e: any) {
}
And then assert that the IBody
is present:
然后断言IBody
存在:
function someFeature(e: any) {
var body :IBody = <IBody> e;
// do something
}
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.
但是,如果您确实需要运行时检查,则需要prototype
在使用 或 作为属性之前查找该函数。虽然这在某些情况下可能会产生误导,但interface
TypeScript 中的 也可能没有发现不匹配。下面是如何检查特定函数是否存在的示例。
It might look like this:
它可能看起来像这样:
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();
}