Making a new object using a factory in TypeScript

My current endeavor involves developing a factory that is capable of generating instances based on a string identifier.
Allow me to walk you through the code...

class A
{

}

class B
{

}

class MyFactory {
    
    private static _instance: MyFactory;

    private _map: { [id: string]: object; } = {};

    private constructor() {
        // Associating the ids with classes
        this._map["A"] = A;
        this._map["B"] = B;
    }

    public createInstance(id: string) : object {
        let newInstance = null;
        if (this._map[id] != null) {
            newInstance = Object.create(this._map[id]);
            newInstance.constructor.apply(newInstance);
        }

        return newInstance;
    }

    public static get instance() {
        return this._instance || (this._instance = new this());
    }
}

I'm currently grappling with what type of information should be stored in the map and how best to utilize it for constructing a new instance from the specified class...

Answer №1

The initial example consistently produces a Function {} object instance as classes were supplied as an argument for Object.create rather than the prototype property of those classes:

//original
newInstance = Object.create(this._map[id]);
//updated
newInstance = Object.create(this._map[id].prototype);

This revised version correctly sets the prototype to the appropriate object, but the issue arises when using object as type; the compiler does not permit access to the .prototype property. Switching to any allows compilation, however, the constructor cannot be used to initialize the object:

newInstance.constructor.apply(newInstance);
// If ordinary functions were in the map, this would function
// but since they are classes, it leads to the runtime error ...
// TypeError: Class constructor A cannot be invoked without 'new' 

An alternative solution could be adjusting the annotations from object to any and then utilizing the new operator.

newInstance = new this._map[id]();

If there was some kind of relationship established between the classes, different types of casts could be applied for improved type check support. Refer to the section on interfaces for constructors in the TypeScript handbook to determine if that aligns with the index declaration for the _map.

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

Getting information from the firebase database

I'm currently working on a web application that utilizes Firebase database. I'm encountering difficulties when trying to access the elements that are labeled as encircled. Can anyone offer any guidance or suggestions? Here is the code snippet I& ...

Using the HTTP Post method to retrieve a file object: a step-by-step guide

Is there a way to utilize a http POST request in order to retrieve a file object? Though the uploading of files to the server using the POST request seems successful and flawless, attempting to fetch the file results in an unusual response: console output ...

Perform a child component function in Angular

I'm working on a project with a child component as a map and a parent component as a form. The parent component has a field for writing the address, and when an address is entered, an HTTP request is triggered to find the latitude and longitude coordi ...

Having trouble with Angular 4 data display? See how to fix a simple example that's

I can't seem to display my data correctly in Angular. When I try, all I get are empty bullet points and an error message that says "Cannot read property of 0 undefined." Even though the code appears to be correct, it's not functioning as expected ...

encountering the issue of not being able to assign a parameter of type 'string | undefined' to a parameter of type

Seeking help with the following issue: "Argument of type 'string | undefined' is not assignable to parameter of type" I am unsure how to resolve this error. Here is the section of code where it occurs: export interface IDropDown { l ...

Tips for showing an image through a button in Angular 4

Currently, I am in the process of creating a simple website and I have encountered an issue. When I click on a button to display an image, it works fine. However, when I click on another button to display a different image, the previous image remains visib ...

Using React hooks with Material-UI: Snackbar displaying only on first occasion and not again

I have identified an issue that can be easily reproduced. Steps to replicate: Step 1: Start a react app and include material-ui in the project: prompt> create-react-app mui-test prompt> cd mui-test prompt> yarn add @material-ui/core @material-ui ...

Receiving an Async Thunk result in a Promise

I have a situation where I am making an Axios promise call from an asyncThunk in my Redux toolkit. I am able to capture the responses using Redux toolkit, but I am struggling to figure out how to handle the error response in the "Rejected" state of the sli ...

The real file that was brought in after indicating a module in the node_modules directory that was coded in Typescript

After creating a typescript module named moduleA, I am ready to publish this package and make it accessible from another typescript project. Currently, for testing purposes, I have installed 'moduleA' using 'npm install ../moduleA'. Th ...

Utilize the type constant to retrieve a specific value in typescript

Is it possible to retrieve the constant value from the type with this specific definition? type Dummy = { type: "dummy" } For instance, something along the lines of Extract<Dummy["type"]> ...

Switch statements in TypeScript may not function properly with type guards when assigning an object to a variable

I'm puzzled as to why the type guard is not working in the example provided below... Considering the following interfaces: interface ParamA { name: 'A'; aaa: boolean; } interface ParamB { name: 'B'; bbb: number; ...

Retrieving Data from Vuetify Component within vue 3

Currently, I am in the process of creating my own wrapper for Vuetify components to eliminate the need to repeatedly define the same props in each component. For example, I aim to develop a custom TextField with defaultProps while still being able to accep ...

Struggling to update TypeScript and encountering the error message "Unable to establish the authenticity of host 'github.com (192.30.253.113)'"

While attempting to update my version of TypeScript using npm, I ran into an issue when trying to execute the following command: localhost:Pastebin davea$ npm install typescript/2.8.4 --save-dev The authenticity of host 'github.com (192.30.253.113)&a ...

The ko.mapping function is throwing an error because it cannot access the property 'fromJS' which is undefined

I am currently exploring typescript and attempting to integrate knockout.mapping into my project, but I'm facing some challenges. Despite installing the necessary libraries for knockout and knockout.mapping, along with their respective "@types" decla ...

Exploring the power of developing AngularJS applications using Typescript and the app

I am currently working on a basic application that utilizes Typescript and AngularJS. In my app, I have used app.js to register my controller and some route parameters: /// <reference path="../scripts/typings/angularjs/angular.d.ts" /> /// <refer ...

Efficiently search and filter items across multiple tabs using a single search bar in the Ionic 2

I am currently working on implementing a single search bar that can filter lists in 2 different tabs within Ionic 2. The search bar is functional, and I have a method for filtering through objects. However, my goal is to allow users to select different tab ...

In Angular 2, templates may not be fully executed when utilizing ngAfterContentInit or ngAfterViewInit functions

When I try to access the DOM of the document, I notice that the template is only partially executed. Using a setTimeout helps me bypass the issue temporarily, but what is the correct way to handle this? import { Component, Input, AfterContentInit } from & ...

Require TypeScript interfaces to include all index types from a union

I have a union type defined as: type A = "a" | "b" | "c"; Now, I want to create an interface like this: interface B { [index: A]: string } However, I need this interface to include all options from the union type, resulting in the following interface ...

What is the method for retrieving the index of an enum member in Typescript, rather than the member name?

Here is an example of how to work with enums in TypeScript: export enum Category { Action = 1, Option = 2, RealEstateFund = 3, FuturesContract = 4, ETFs = 5, BDRs = 6 } The following function can be used to retrieve the enum indexe ...

Angular2 provides a simple way to toggle the visibility of modal boxes on a web page

I'm encountering an issue with the ng2 modal in my template - it's not opening or hiding through my TypeScript code. <modal id='saveeditsmodal'> <modal-header> <h4 class="modal-title">Editing item(s) in ...