I'm writing a component system and trying to achieve the following:
abstract class Component {}
class FooComponent extends Component {
doFooStuff(): void {
console.log("foo stuff");
}
}
class BarComponent extends Component {}
const entity = Entity();
entity.addComponent(FooComponent);
entity.addComponent(BarComponent);
const foo = entity.getComponent(FooComponent);
if(foo !== undefined) {
foo.doFooStuff();
}
I'm not sure if it's a correct approach but it seems nice.
The problem is that I can't figure out how to do this.
class Entity
{
protected readonly components = new Map<typeof Component, Component>();
addComponent(Constructor: typeof Component): void {
// TypeScript is against potentially creating an instance of an abstract class
this.components.set(Constructor, new Constructor(this));
}
// I'm lost here. I can see that instead of FooComponent instance being returned, it returns (typeof FooComponent), but I don't know how to solve this
getComponent<T extends typeof Component>(componentClass: T): T | undefined {
const component = this.components.get(componentClass);
if (component !== undefined && component instanceof componentClass) {
return component as unknown as T;
}
return undefined;
}
}