【发布时间】:2019-10-26 19:23:01
【问题描述】:
问题
错误:Property 'attach' does not exist on type 'Component'.
如何返回存储在自定义字典类型中的任意子类,并在字典类型具有超类的返回值时使用仅存在于子类上的方法?
上下文
我有一个有很多子类的Component 类。
我的 GameActor 类可以附加组件。附加组件存储在ComponentContainer 成员中,该成员是自定义类型,可以是Component 的任何子类。例如。 MovementComponent、HealthComponent、EventComponent等都可以存储在ComponentContainer中。
当我检索附加的组件时,当我尝试从检索到的组件中调用方法时,我收到上面的“属性不存在”错误。如果我打开浏览器的开发工具,我可以看到返回类型的日志看起来像 实际上是子类类型
ComponentContainer 类型定义
//globals.d.ts
// ComponentContainer type definition
// populated data structure will look like:
// {
// "EventComponent": EventComponent,
// "MovementComponent": MovementComponent,
// "FooComponent": FooComponent
// // etc...
// }
type ComponentContainer = {
[componentName: string]: Component;
}
GameActor 有很多方法可以添加、删除、获取和列出附加组件。
//GameActor class that can have Components attached to it
export abstract class GameActor extends GameObject implements IGameActor {
protected components: ComponentContainer;
constructor() {
this.components = {};
}
public getComponent(key: string): Component|null {
return this.components[key];
}
}
// Player subclass of GameActor
export class Player extends GameActor implements IPlayer {
//Player class code here...
}
//Component superclass
export abstract class Component {
protected typeId: string;
public getTypeId(): string {
return this.typeId;
}
}
//EventComponent subclass
export class EventComponent extends Component implements IEventComponent {
public attach(event: Event|CustomEvent): void {
//Attach code here...
}
}
现在我想在代码的其他地方执行以下操作:
this.getComponent("EventComponent").attach(PlayerDeathEvent.create(this));
此时我收到错误。如果我注销以下代码,则两者的类型似乎都是EventComponent。
let ec = this.Player.getComponent("EventComponent");
let t = new EventComponent();
我希望 .attach 不会抛出错误,因为编译器知道组件的类型为 EventComponent。
【问题讨论】: