Tailored production method based on specific criteria

One of my challenges is to create a versatile factory method using typescript.

The main objective is to initialize a class based on its name using generics, instead of employing if/else or switch statements.

I am aiming for similar functionality as this example:

document.createElement("p");

createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K];

interface HTMLElementTagNameMap {
    "a": HTMLAnchorElement;
    "abbr": HTMLElement;
    "address": HTMLElement;
    "applet": HTMLAppletElement;
...
}

I encountered an obstacle when attempting to instantiate a class type:

class A {

  constructor(private name:string,private id:number){

  }
}

class B extends A{

}

class C extends A{

}



interface stringToClassMap{
  'A':A;
  'B':B;
  'C':C;
}

// Should return a new instance every time
const obj: stringToClassMap = {A:new A('x',123),B:new B('x',123),C:new C('x',123)}

function creator<K extends keyof stringToClassMap>(key:K): A{
  return new obj[key](); 
}

Thank you!

Answer №1

class Z {
  constructor(public x: string) {}
}

class D {
  constructor(private label: string, private number: number) {}
}

class E extends D {}

class F extends Z {}

type Constructor<U> = new (...params: any) => U;
interface ClassMap {
  D: Constructor<D>;
  E: Constructor<E>;
  F: Constructor<F>;
  Z: Constructor<Z>;
}
// Generate new instance each time
const item: ClassMap = {
  D: D,
  E: E,
  F: F,
  Z: Z
};

function generator<L extends keyof ClassMap>(
  index: L,
  ...properties: any
): ClassMap[L] extends Constructor<infer N> ? N : never {
  const Element = item[index];
  return new Element(...properties) as any;
}

const eObj = generator("D", "");
const fObj = generator("E", "");
const gObj = generator("F", "");
const zObj = generator("Z", "");

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

Exploring TypeScript's Classes and Generics

class Person { constructor(public name: string) {} } class Manager extends Person {} class Admin extends Person {} class School { constructor(public name: string) {} } function doOperation<T extends Person>(person: T): T { return person; } ...

The onChange function in React is not behaving as I anticipated

Consider the following data structure for tables: an array of objects containing nested objects: [ { "1": { "1": "Item s ", "2": "Manufacturer ", "3" ...

Diverse behaviors exhibited by an array of promises

I've developed a function that generates an array of promises: async addDefect(payload) { this.newDefect.setNote(payload.note); this.newDefect.setPriority(payload.priority); const name = await this.storage.get(StorageKeys.NAME); ...

Best practice for incorporating types into a Redux-toolkit reducer

As someone who is relatively new to TypeScript, I have a specific goal in mind. I am looking to create an interface where: interface ActionType { fieldName: {any one key from the interface FormStateType listed below such as 'name', 'age&ap ...

Tips for monitoring dispatch in fetch/middleware functions

Just testing a basic webpage <template> <HomeTemplate /> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ async fetch(context) { // or middleware(context) await context.store.disp ...

Mismatched data types for function arguments

const x: Example = { toY: (y: Maple) => { return y.p; } }; interface Example { toY: (y: Pine) => void; } interface Pine { c: string; } interface Maple extends Pine { p: boolean; } Despite the warning for interface names ...

Attempting to establish a connection with Redis through the combination of TypeScript and Node.js

Currently, I am attempting to establish a connection with Redis using TypeScript and Node.js. However, I am encountering an issue where **error TS2693: 'RedisStore' is designated as a type but is being utilized as a value in this context.** let r ...

Encountered difficulties in deploying functions on Firebase Cloud Functions

While developing the Firebase Cloud Functions, I organized the files based on each function. Unfortunately, numerous errors occurred during deployment. Error [debug] [2022-07-19T14:36:17.677Z] <<< [apiv2][body] GET https://us.gcr.io/v2/xxxxxx/gcf ...

type Y does not contain property X

When I encounter this error message: The property 'module' is missing in the type 'Menu'. The property 'parentId' is not found in the type 'Menu'. the code snippet triggering it appears like this: private menus: ...

What strategies can be used to address inconsistencies between the type system and runtime behavior?

I have created a unique TypeScript type called Awaitable<T> with the goal of ensuring that Awaited<Awaitable<T>> is always equal to T. export type Awaitable<T> = | (T extends Record<'then', Function> ? never : T) ...

What is the best method for altering a route in React while utilizing Typescript?

I recently started coding along with the ZTM course and am working on a face recognition app. Instead of using JavaScript, I decided to use TypeScript for this project in order to avoid using the any type. However, as a beginner in this language, I'm ...

The Angular-slickgrid is encountering an issue where it is unable to access the property "hostView" as it

Hey there developers, I've been experimenting with the angular slickgrid library and attempting to incorporate the rowDetailView feature it offers. The issue I'm facing is that while I can expand the view by clicking on it, I'm unable to c ...

How can I effectively test static navigationOptions using Jest and Enzyme in a React Navigation and TypeScript environment?

Currently, I am developing a React Native app using TypeScript. For component testing, I rely on Jest and Enzyme. Additionally, I have integrated React Navigation into my project. On one of the screens, the navigationOptions are as follows: static naviga ...

What is the best way to effectively use combinedLatestWith?

https://stackblitz.com/edit/angular-ivy-s2ujmr?file=src/app/country-card/country-card.component.html I am currently working on implementing a search bar in Angular that filters the "countries$" Observable based on user input. My approach involves creatin ...

Is there a way to transform Observable<Observable<Organization>[]> into Observable<Organization[]>?

I have implemented ngrx/store in my project. .map((p: Observable<Organization>[]) => { return new usersActions.GetOrganizationSuccess(p); }) The GetOrganizationSuccess action is designed to accept Organization[] as the payload. Is ...

The functionality of connect-flash in Express JS is compromised when used in conjunction with express-mysql-session

I am facing a unique issue in my project. I have identified the source of the problem but I am struggling to find a solution. My project utilizes various modules such as cookie-parser, express-mysql-session, express-session, connect-flash, passport and m ...

Unable to make changes to the document

Having trouble updating a document by ID using mongoose and typescript. I'm testing the api and passing the id as a parameter. I've experimented with different methods of updating by ID, but for some reason, it's not working. Can update by ...

Is it possible to incorporate the arrow function within the debounce function?

export const debounce = (callback: Function, ms = 300) => { let timeoutId: ReturnType<typeof setTimeout> return function (...args: any[]) { clearTimeout(timeoutId) timeoutId = setTimeout(() => callback.apply(this, args), ms) ...

Possible revision: "Dynamic property naming in TypeScript interface based on specified type"

The concept might seem complex, but here's the gist of it. I have a User interface that may or may not contain certain properties depending on where it is fetched from. For example, there are optional properties like role and client_details. export i ...

Tips on adjusting the Leaflet Map's zoom level to display all markers in React Leaflet

I am currently working on a project with React Leaflet map that requires changing the center and zoom based on a set of markers. The goal is to adjust the zoom level so that all the markers are visible on the map. To achieve this change in view, I am util ...