Search code examples
javascripttypescriptgame-engine

Typescript: Serialize interface types to array of classes


I have problem with typescript typings.

Currently, I am working on small game engine, which uses entity-component-system model. I want to "serialize" types of interface into the array of classes (a types of each interface property) to inform system about needed components.

What I want to achieve ideally:

export interface IMovable {
    position: CompPosition;
    velocity: CompVelocity;
}

export class MoveSystem extends System<IMovable> {

    // This array should have type, to ensure all components classes from IMovable are listed.
    protected requiredComponents = [ CompPosition, CompVelocity ];

    /// ...

}

What I want to do at least:

export interface IMovable {
    position: CompPosition;
    velocity: CompVelocity;
}

export class MoveSystem extends System<IMovable> {

    /* The properties of requiredComponents have the same name as in interface, but their types are 
       different - in interface, the type requires instances (which I want to keep this way in the 
       interface), but requiredComponents should contain classes. */
    protected requiredComponents = {
        position: CompPosition, 
        velocity: CompVelocity 
    };

    /// ...

}

Thanks for every suggestion.


Solution

  • I finally found solution. Not the best one possible, but it works the way it should:

    type Class<T> = new(...args: any[]) => T;
    
    type ComponentStore<T> = { [P in keyof T]: Component };
    type RequiredComponents<T extends ComponentStore<T>> = { [P in keyof T]: Class<T[P]> };
    
    abstract class System<T extends ComponentStore<T>> {
    
        protected abstract requiredComponents: RequiredComponents<T>;
    
        // ...
    
    }
    
    interface IMovable {
        position: CompPosition;
        velocity: CompVelocity;
    }
    
    class MoveSystem extends System<IMovable> {
    
        protected requiredComponents = {
            position: CompPosition,
            velocity: CompVelocity
        };
    
        // ...
    
    }
    

    But thanks everyone, who tried or even read it.