我有以下课程&接口:
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'.
谢谢 - 戴夫
答案 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();
}