Creating subclass mappings and defining subclasses dynamically using Typescript at runtime

I am puzzled by the structure of 3 classes: A, B, and C. Both B and C extend the abstract class A.

abstract class A {
  public name: string;

  constructor(name: string) {
    this.name = name;
  }

  abstract getName(): string;
}

class B extends A {
  getName(): string {
    return "B: " + this.name;
  }
}

class C extends A {
  getName(): string {
    return "C: " + this.name;
  }
}

In an attempt to create a subclass of an abstract class at runtime using the code below, I encountered a compiler error stating: "Cannot create an instance of an abstract class."

const classes: { [type: string]: typeof A } = {
  b: B,
  c: C,
};

function test(type: string, name: string) {
  if (!classes.hasOwnProperty(type)) {
    throw new Error(`Invalid type: ${type}`);
  }
  const _class = classes[type];
  return new _class("name");  // compiler error: Cannot create an instance of abstract class.
}

let x = test("b", "bob");
console.log(x.getName());

If I modify the classes definition to

{ [type: string]: typeof B | typeof C }
, it functions properly.

const classes: { [type: string]: typeof B | typeof C } = {
  b: B,
  c: C,
};

function test(type: string, name: string) {
  if (!classes.hasOwnProperty(type)) {
    throw new Error(`Invalid type: ${type}`);
  }
  const _class = classes[type];
  return new _class("name");
}

let x = test("b", "bob");
console.log(x.getName());

This method may lead to a rapid increase in the definition list like

typeof B | typeof C | typeof D | typeof E | etc.
. Is there a more sophisticated approach to manage this situation?

Answer №1

If you want to assign values on the map using a constructor that takes a string input and returns A, you can do it like this:

type ConstructorA = new (name: string) => A;

const mapping: { [key: string]: ConstructorA } = {
  x: X,
  y: Y,
};

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

Develop a universal function for inserting information into an array within a data set

I need assistance with my Typescript code. I am currently working on a method that pushes data into an array in a mongoose collection. However, the issue I'm facing is that the value is not being passed dynamically to the Key field in the $set operato ...

Obtaining distinct form control values for replicated form fields with Angular

Issue with Dynamic Form Duplicates: I am currently working with a reactive form that has two fields - name and value. There is an add button that duplicates the form by copying these fields. The challenge I am facing is with updating the values of the dup ...

How can this be happening? It's expected that items will be printed, but for some reason

I'm struggling to figure out why the console.logs aren't showing up. import { GenericRepository, getGenericRepository } from '../src/database/repository/GenericRepository'; import { start, stop } from '../src/index'; import r ...

What is the best way to eliminate the final character in an input value once it has passed through regex validation in Angular8

Hello! I am attempting to remove the last digit of a string and update the input value each time my function checks if the input value passes a regex test on keypress. Initially, it works correctly, but then it adds an extra digit. After that, it works a ...

How to deliver various static files in NestJS using different paths and prefixes?

I've set up static file serving for developer documentation using the following code: app.useStaticAssets(docsLocation, { prefix: "/docs/" }) Now I have another directory with more static content that I want to serve. Is it possible to serve from ...

What is the alternative method for applying a CSS class in the click event in Angular 7 without relying on ng-Class or ng-Style?

Is there a way to dynamically add or remove CSS classes to HTML elements in Angular7 without relying on Ng-Style and Ng-Class directives? I'd like to achieve this functionality when clicking on the elements. Appreciate any insights you can provide. T ...

How do you transfer byte[] data using a DTO in Java Spring?

I am currently facing an issue with my server-side application. The problem arises when attempting to convert a Blob to an Excel file on the front-end, specifically when the byte[] is sent within a DTO. When sending a POST request from the back-end (sprin ...

Angular generates a dynamic interface to fetch data from Wordpress REST API posts (special characters in property names are causing issues)

I've been developing a front-end Angular application that interacts with the Wordpress REST API to fetch and display post data. My goal is to create an interface to handle the responses and render the posts in the template. However, I encountered an ...

Having trouble retrieving a value from a reference object in React Typescript?

Struggling with a login form issue in my React TypeScript project. Below is the code for the react login form: login-form.tsx import * as React from 'react'; import { Button, FormGroup, Input, Label } from 'reactstrap' ...

Variability in Focus Behavior while Opening a URL in a New Tab with window.open()

Here is a code snippet I have been using to open a URL in a new tab: window.open(urlToOpen, '_blank', 'noopener noreferrer'); The issue I am experiencing is that when this code is executed for the first time, it opens the URL in a new ...

Creating number inputs in Ionic 2/3 using alerts

I am currently working with Ionic 3.x on my macOS system. The issue I am facing is as follows: I have an array that contains a number and another array consisting of names. table: { number: number, names: string[] } = { number: 0, names: ['& ...

I want to use Angular and TypeScript to play a base64 encoded MP3 file

I am attempting to play a base64 encoded mp3 file in an Angular application. I have a byteArray that I convert to base64, and it seems like the byte array is not corrupted because when I convert it and paste the base64 string on StackBlitz https://stackbli ...

What is the process for extracting the background color from a typescript file in Angular and connecting it to my HTML document?

My typescript array population is not changing the background color of my div based on the values in the array. I've attempted to set the background using [style.backgroundColor]="statusColor[i]", where statusColor is an array declared in my typescrip ...

Is there a way to determine the height of the ion-footer?

Is there a way to obtain the height of the ion-footer element in Ionic2? I want to calculate the initial window height minus the ion-footer height, but I am currently only able to get the overall window height. I'm not interested in retrieving the ...

Leveraging Fastify's preHandler middleware functionality

Implementing a middleware to validate user authentication before accessing the specified route. Encountering an issue where tokenService inside tokenController is showing as undefined when passing tokenController.authUser as a middleware. However, the met ...

Is there a syntax available for type annotation of arrays created from pre-declared variables?

According to my standards, all possible annotations are required in TypeScript. Therefore, TypeScript-ESLint is prompting me to annotate the `[ responseData, cognitoUser ]`. However, when I try to use the syntax `[ responseData1: ResponseData1, responseD ...

Incorporating HTML code within a .ts file: a basic guide

I'm relatively new to Angular, but I've been given a project that's built with Angular. As I examine the .ts file containing the list of property types, I need to wrap a span around the label text. Is this doable? Here is the current list ...

Can you explain the variance between Next.js and Create React App?

I've been curious about understanding the distinctions between Next.js and Create React App (CRA). Both aim to simplify our lives when developing front-end applications with React. While researching online, I came across a key difference: Next.js o ...

Creating Empathetic User Experiences with Next 12 and SWC: A Guide to Harnessing import.meta.url

In my Next.js 12 App with the Rust Compiler, I am utilizing Jest and WebWorkers. In one of my files, I am using import.meta.url. to create the worker. The issue arises when Jest throws an error, stating that import.meta.url cannot be used outside of an ES ...

The properties are absent in Angular Service - Observable

I recently started learning angular and I'm struggling to make this HTTP get request work. I have been looking at various examples of get requests for arrays and attempted to modify one for a single object (a user profile) but without success. The err ...