Dynamic class/interface in Typescript (using Angular)

Is there a way to achieve intellisense for an object created with a dynamic class by passing parameters?

Here is the code snippet:

Main:

let ita: any = new DynamicClass('ITA');
let deu: any = new DynamicClass('DEU');

The DynamicClass used to create dynamic classes:

export class DynamicClass {
  constructor(className: string) {
    if (Store[className] === undefined || Store[className] === null) {
      throw new Error(`Class type of \'${className}\' is not in the store`);
    }
    return new Store[className];
  }
}

Sample dynamic classes ITA and DEU:

export class ITA {
  id: string;
  name: string;
  pck: string;

  constructor() {
    console.log('ITA class');

    this.id = '1';
    this.name = 'ita';
    this.pck = '4';
  }
}

export class DEU {
  id: string;
  name: string;
  size: string;

  constructor() {
    console.log('DEU class');

    this.id = '1';
    this.name = 'ita';
    this.size = '5';
  }
}

export const Store: any = {
  ITA,
  DEU,
}

Answer №1

Here is how you can perform the casting:

let ita: ITA = new DynamicClass('ITA') as ITA;
let deu: DEU = new DynamicClass('DEU') as DEU;

Answer №2

A factory function can be created to only accept known class names, with the return type resolved based on the provided key (class name):

const Store = {
    ITA,
    DEU,
} as const;

type ClassMap = typeof Store;

const createClass = <Key extends keyof ClassMap>(key: Key) =>
    new Store[key] as InstanceType<ClassMap[Key]>;

const instance = createClass('ITA'); // instance is of ITA type

createClass('foo'); // Error: '"foo"' is not assignable to '"ITA" | "DEU"'

Playground

Answer №3

My recommendation would be as follows:

export const Store = {
  ITA,
  DEU,
};

let italy = new Store['ITA'];        // Italy type inferred to ITA
let germany = new Store['DEU'];        // Germany type inferred to DEU
let x = new Store['MISSING_PROP']; // does not compile

Playground

However, I fail to see any advantages compared to:

let italy = new ITA();
let germany = new DEU(); 

Update (after clarifying question)

Have you considered defining a union type for accepted languages and utilizing a switch statement:

type Langs = 'ITA' | 'DEU'

function doSomething(lang: Langs): string { 
  switch (lang) {
    case 'ITA':
      const italy = new ITA();
      return italy.name;
    case 'DEU':
      const germany = new DEU();
      return germany.name + germany.size;
  }
}

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

Experience the magic of live streaming with our cutting-edge technology bundle featuring RTSP streaming, AspNet 5 API integration, FFM

Description: I am working on an API (ASP.Net 5) that connects to an IP Camera through RTSP. The camera sends a h264 stream converted with ffmpeg as an m3u8 stream, which is then returned to the Angular client in the following manner: public async Task< ...

Having difficulty configuring unique paths for multiple APIs using Socket.IO, ExpressJS, and Nginx

I am currently working on setting up multiple APIs on a single VPS and serving them through Nginx. My goal is to have all of them organized in separate sub-locations, as shown in the example below: For Express remote paths: [myhost].com/apps/app1/api [myh ...

AngularJS - Setting an initial delay for ng-bind

We have a span element with the following attributes: <span role="link" ng-show="showLink()" ng-bind="textLink"></span> (Just an fyi: we implemented a fade-in, fade-out animation for this link, hence the use of ng-show instead of ng-if) The ...

Decoding a JavaScript object when receiving it as JSON through a POST request

While browsing through various SO posts, I came across the statement "javascript is JSON". However, I am struggling to apply this concept in my application. My issue arises when I try to perform a POST request using jQuery. $.ajax({ type: &apo ...

Trigger modal on designated ID

My code includes a script that assigns a specific id to a button using a variable $i in a for loop: <button id='myBtn$i'>Open Modal</button>. This id should allow me to open specific modals with the corresponding $i value: <div id= ...

Discover the method to calculate the combined file size of multiple uploads with jquery

One of the challenges I'm facing is ensuring that users can only upload multiple files if the total size does not exceed 3GB. Is there a way I can enforce this limit? Below is the current code snippet I am using: var fileCount = 0; var showFileCo ...

Encountered an error in NodeJs with mongoDB: TypeError stating that property 'fullname' is not defined

I am having issues storing user-entered data from an HTML form into MongoDB. The error message I receive is "TypeError: cannot read property 'fullname' of undefined" TypeError: Cannot read property 'fullname' of undefined at C:&bso ...

Using TypeScript and webpack, include the access_token in the http header when making requests with axios

I need to include an access_token in the header of axios, following this example: https://github.com/axios/axios#global-axios-defaults Currently, I am fetching the access_token using razor syntax, which is only accessible in CSHTML files. https://github ...

How to efficiently retrieve automatically generated elements by ID in Angular 2

In order to create a 6x6 grid, I am using the following code: <ion-grid> <ion-row *ngFor="let rowIndex of createRange(6)" [attr.id]="'row-'+rowIndex"> <ion-col col-2 *ngFor="let colIndex of createRange(6)" [attr.id]= ...

"Optimizing the placement of a range slider for pricing options

As a beginner in HTML, CSS and JS, I recently faced the challenge of creating a price slider range on a website. However, I am struggling with repositioning it. After copying the code from this link, I noticed that the slider is positioned at the top of th ...

working with JSON array information

I have a JSON array retrieved from a database that I need to manipulate. Currently, it consists of 8 separate elements and I would like to condense it down to just 2 elements while nesting the rest. The current structure of my JSON looks like this: { "i ...

Capturing Input Data Dynamically with Angular Forms

Is there a way to retrieve values from an unknown number of input fields in Angular? This is the code I am using to generate the input fields: <form (ngSubmit)="submit()" #custom="ngModel"> <div *ngIf="let elem of arr"> <input ...

Displaying various charts in a single view without the need for scrolling in HTML

How can I display the first chart larger and all subsequent charts together in one window without requiring scrolling? This will eventually be viewed on a larger screen where everything will fit perfectly. Any recommendations on how to achieve this? Here ...

Is there a way to reverse the hover effect on div elements?

Let's start by examining the code I've written: HTML: <div class="button_container"> <div class="inner_button"> <a href="#" class="button_text">Button</a> </div> <div class="button_side"> ...

Error message "SyntaxError: Unexpected token < in JSON at position 0" encountered while using AJAX

When data is sent through an ajax request and processed, a returned array is encoded into json format. $response = array( 'data' => $leaveData, 'message' => 'Event added successfully', ...

Looking for a new slider option to replace the traditional Conveyor belt slideshow?

I have successfully used the Conveyor belt slideshow script from http://www.dynamicdrive.com/dynamicindex14/leftrightslide.htm. Now, I am looking to find another script that works similar to this one. Does anyone have any recommendations for a tool that ...

Having difficulty retrieving items from Mongoose-Node database

I am currently working with a Mongodb database that stores resume objects. These objects contain various skills information and I have set up a node-express server to query the database based on specific skills. For example, when querying for a skill like ...

What is the best way to show an array within a string using javascript?

Take a look at this code snippet : const names = ["Alex", "John", "Kit", "Lenny"]; for(let i = 0; i < 4; i++) { $("body").append("<p>" + names[i] + "</p>'); }; Can you figure out how to dynamically add each item in the 'names&a ...

Having trouble parsing a JSON string in your JavaScript code?

As a java developer transitioning to JavaScript, I'm faced with the task of parsing a JSON string retrieved from a WebService. Here is the JSON String: { "myArrayList": [ { "myHashMap": { "firstName": "Clara", ...

What is causing the label's color to remain the same?

Once the page has loaded, the label color (which reads "enter your name") is supposed to change to red. However, despite the script being in place, the color remains unchanged. What could be the reason for this? SCRIPT window.onload = initiateScript; fu ...