Trying to figure out how to dynamically add different types of components to a game object in TypeScript.
After consulting the TypeScript documentation on interfaces, I discovered a unique approach for dealing with constructors in interfaces, which led me to the following solution.
Component setup
export interface IComponentConstructor {
new(gameObject: GameObject, ...args: any[]): IComponent;
}
export interface IComponent {
update?(): void;
}
export const createComponent = (
ctor: IComponentConstructor,
gameObject: GameObject,
...args: any[]
): IComponent => {
return new ctor(gameObject, args);
}
PlayerComponent
export class PlayerComponent implements IComponent {
constructor(gameObject: GameObject, ...args: any[]) { }
public update() { }
}
GameObject
export class GameObject {
components: IComponent[] = [];
public addComponent(ComponentType: IComponent, ...args: any[]) {
const component = createComponent(
ComponentType,
this,
args
);
this.components.push(component);
return component;
}
Facing an issue where passing different component types like PlayerComponent
, EnemyComponent
, NpcComponent
, etc. to addComponent
is not working due to type discrepancies:
Argument of type 'IComponent' is not assignable to parameter
of type 'IComponentConstructor'.
Type 'IComponent' provides no match for the signature
'new (gameObject: GameObject, ...args: any[]): IComponent'
Is there a way to resolve this in TypeScript?
PS: The following workaround does function, but it does not meet the requirement of passing PlayerComponent
into the addComponent
method:
const component = createComponent(
PlayerComponent,
this,
args
);