Converting TypeScript interface types into an array of classes: Serialization process

I am encountering an issue with typescript typings in my current project. Specifically, I'm developing a small game engine that follows the entity-component-system model. My goal is to convert types of interfaces into an array of classes to define the necessary components for the system.

My ideal outcome would be:

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

export class MoveSystem extends System<IMovable> {

    // This array should specify all component classes from IMovable.
    protected requiredComponents = [ CompPosition, CompVelocity ];

    /// ...

}

Alternatively, I aim to achieve:

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

export class MoveSystem extends System<IMovable> {

    /* The properties of requiredComponents have the same name as in the interface,
       but their types are different - instances in the interface and classes in 
       requiredComponents. */
    protected requiredComponents = {
        position: CompPosition, 
        velocity: CompVelocity 
    };

    /// ...

}

Any suggestions or advice are greatly appreciated.

Answer №1

After careful consideration, I have devised what I believe to be the optimal solution for this situation. It seems that achieving this task using an array approach may not be feasible or efficient from a developer standpoint, so my choice is to utilize the object method.

class Position implements Component {
    x: number = 0
    y: number = 0
    readonly requiredComponents: {}
}

class Velocity implements Component {
    velX: number = 0
    velY: number = 0
    readonly requiredComponents: {}
}

type ComponentConstructor<T> = new(...args: any[]) => T

interface Component<A = {}, B = {}, C = {}, D = {}> {
    readonly requiredComponents: A & B & C & D
}

interface IMovable {
    position: ComponentConstructor<Position>
    velocity: ComponentConstructor<Velocity>
}

class Player implements Component<IMovable> {
    readonly requiredComponents = {
        position: Position,
        velocity: Velocity,
    }
}

If there is additional information on how these components will interact, I could possibly offer an even more refined solution. At this time, I still question the necessity of your current approach.

Answer №2

I have finally uncovered a solution. While it may not be the most optimal, it does fulfill its intended purpose:

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
    };

    // ...

}

Many thanks to all those who made an attempt or took the time to read through this.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I seem to be having issues with the way the lighting is functioning in three.js; it is not acting

There's this fiddle I'm working on, you can check it out here. It contains the html/js code for a terrain generated by PHP. The problem I'm facing is that the shadow and other renderings are not displaying as expected. Here is my current l ...

Reasons for aligning inline elements with input boxes

I am facing a challenge with aligning a series of inline elements, each containing an input text box, within a single row. The number and labels of these input boxes can vary as they are dynamically loaded via AJAX. The width of the div housing these inli ...

Increasing values in Mongoose using $inc can be done by following these steps

I've been struggling to increment a field value using $inc in my code. My schema looks like this: var postSchema = mongoose.Schema({ title : { type: String, required: true }, body : { type: String, default: '' }, coun ...

Tips for transferring the default value from the form input to the payload

When creating an edit form within a Modal in React, I have encountered an issue. The form inputs are initially populated with default values from props (name, age, strength). If I only change one input value, the payload logged to the console shows empty s ...

Search form with a variety of fields that allows for searching without needing to repeat the component for each condition

I am currently facing an issue with my form that consists of multiple fields, each used to search through an API and display matching data in a table below. While I have successfully implemented this for one field, I now need it to work for all fields with ...

getting TypeScript configured with webpack

I am currently using Typescript to develop a back-end API utilizing graphql and express. To manage the project development and building process, I have implemented webpack. As part of my setup, I am employing raw-loader in order to load graphql schemas an ...

Algorithm for File Naming

Given an array of desired file names in the order of their creation, where two files cannot have the same name. If a file has a duplicate name, it will be appended with (k), where k is the smallest positive integer that creates a unique name. Output an ar ...

Press on a specific div to automatically close another div nearby

var app = angular.module('app', []); app.controller('RedCtrl', function($scope) { $scope.OpenRed = function() { $scope.userRed = !$scope.userRed; } $scope.HideRed = function() { $scope.userRed = false; } }); app.dire ...

Dynamic SVG positioning

Looking for a way to make this svg shape relative to its containing div? Fiddle: http://jsfiddle.net/8421w8hc/20/ <div> <svg viewBox="0 0 1000 2112" style="" xmlns="http://www.w3.org/2000/svg" version="1.1"> <path id="ma" st ...

There is a syntax error that occurs when attempting to begin a key with a hyphen (-)

Upon initializing the following object, an error is thrown. var postData ={ file_path : "https://s3-us-west-2.amazonaws.com/ps/eams/6-48K.mxf", template_type : "1", template_name : "Basic Tests", job_type : "0", user_note : "my job", access-ke ...

Showing the test steps in an Allure report for a Jasmine Protractor framework test case

Is there a way to include test steps in an Allure report for Protractor? I am facing an issue where the test steps are not showing up as they do for Java language tests. The official Allure report documentation also does not provide any code samples for ...

Breaking the website with an HTML comment

Upon clicking a link to another page, I encountered the error message "Failed to execute 'insertBefore' on 'Node." Here is the code snippet that was causing the issue: <template name="reminderPage"> <a href="/newRemind">New! ...

Encountering Error with Axios in Nuxt while Navigating Pages

Working on a nuxt application utilizing axios for API calls. In my index.vue file, I have the code snippet below. <template> <div> <Hero /> <Homebooks :details="details" /> </div> </template> <s ...

Assign a value to the input field based on changes made in another input field

I am brand new to the world of JavaScript and currently grappling with setting a value in an input field based on the onchange event of another input field. Here is my code sample for input field 1: <input type='text' onchange='methodTh ...

Store the ID of a div in a variable

Currently, I have transformed rock paper scissors from a terminal/console game using prompts and alerts to something playable in a web browser through the use of the jQuery library. In order to achieve this transition, I created images for each hand - roc ...

When updating the HTML content, JavaScript is outputting the code as text instead of running it

I am encountering an issue with adding the body content of a JSON file, which contains HTML code, to my existing HTML. Instead of executing the code, it appears as text within paragraph or header elements. I have searched through various discussions but ha ...

Having trouble getting the items to show up on the canvas

I have been struggling to implement JavaScript on a canvas in order to display mice in the holes using the mouse coordinates. Despite trying many different methods and spending close to a month on this project, I still can't seem to get it to work acr ...

Safari's anchor links tend to leap higher than necessary

One of the anchor links on my website is behaving strangely in Safari, both on iPhone and MacOS. Instead of scrolling to the correct position of the anchored div, it scrolls to a random location around 400-500px higher than it should be. All other anchor l ...

The jQuery toggle function seems to be skipping alternate items

I have recently started learning Javascript and JQuery. Currently, I am working on creating a comment system where you can click reply to display the form. However, I'm facing an issue where the form only shows up for the first comment reply, not for ...

A custom script developed to detect the presence of the numeric combination "11" and promptly notify the

I am attempting to develop a unique chrome extension that detects typing errors in orders. For example, if the user accidentally types "11" instead of "1", an alert should be triggered. However, I am encountering an issue where the script is running in an ...