How can Array<T> in Typescript be used to dynamically determine and generate a new instance of T?

My challenge involves managing multiple typed Arrays containing different objects. I am searching for a way to create a function that can add a new blank object to any array, as long as the type has an empty constructor available.

Being new to Angular 2 and Typescript, I need this functionality for arrays that are part of a form. Having numerous arrays, I would greatly benefit from a generic solution that works universally.

someObject {
    constructor() { this.someField = ""; ... }
    someField: string;
    ...

}

someOtherObject {
    constructor() { this.someOtherField = ""; ... }
    someOtherField: string;
    ...
}

Array<someObject> someArray = someObject[{...}, {...} ...];
Array<someOtherObject> someOtherArray = someOtherObject[{...}, {...} ...];


// My desired function should be able to work with either of the above arrays
// Although 'new T()' is not valid in TypeScript

addRow<T>(array:Array<T>) : void {
    array.push(new T());
}

I have knowledge of using instanceOf to identify an object's specific class. However, I'm yet to discover a method for accessing the type as an object within an Array.

The following code could potentially solve my issue, but it may fail when the array is empty. Despite this, it should still retain its typing to which theoretically enables creation.

if(array.length > 0 && array[0] instanceOf(someObject)) { 
    array.push(new someObject()); 
} 
// else if instance of someOtherObject... and so forth

Is there a more effective way to achieve my goal, or perhaps a technique I am currently unaware of? Thank you.

EDIT: According to Alexander's suggestion, achieving dynamic behavior in Typescript is possible through:

addRow<T>(array:Array<T>, c: {new(): T}) : void {
    array.push(new c());
}

addRow(someArray, someObject);
addRow(someOtherArray, someOtherObject);

However, usage in HTML poses limitations: e.g.

<div class="btn btn-default" (click)="addRow(someArray, someObject)"></div>
won't be functional due to the lack of understanding the someObject class definition in HTML context.

Answer №1

Based on the information from https://www.typescriptlang.org/docs/handbook/generics.html (specifically "Using Class Types in Generics"), the suggested approach is as follows:

class anotherObject {
    constructor() { this.anotherField = ""; }
    anotherField: string;
}

class anotherOtherObject {
    constructor() { this.anotherOtherField = ""; }
    anotherOtherField: string;
}

var anotherArray: Array<anotherObject> = [];
var anotherOtherArray: Array<anotherOtherObject> = [];

function addRow<T>(array: Array<T>, c: {new(): T}) : void {
    array.push(new c());
}

addRow(anotherArray, anotherObject);
addRow(anotherOtherArray, anotherOtherObject);

The reason behind this approach lies in the necessity to pass a constructor function as a parameter in order to instantiate it. Generic declarations serve for type checking by the compiler and do not result in actual code generation, unlike passing a constructor function.

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

Utilize a function to wrap the setup and teardown code in Jest

I am attempting to streamline some common setup and teardown code within a function as shown below: export function testWithModalLifecycle() { beforeEach(() => { const modalRootDom = document.createElement('div') modalRootDom.id = M ...

What is the best return type to use for a TypeScript function that returns an AsyncFunction?

From my experience, this code should work just fine... let DynamicFunction = Object.getPrototypeOf(dynamic function(){}).constructor; export function generateJsFunction(event: string, body: string[]): any { return new DynamicFunction(body.join("\n ...

Tips for invoking a service from another in angular version 6

The following code snippet showcases Service 1, specifically the uploadAttachment method which executes an http post call. This method is invoked from Service 2. However, in Service 2, the instance of Service 1 is consistently undefined, resulting in a fai ...

The data retrieved from the backend is being stored in an object, however, it is not directly accessible through

After receiving data from the backend and storing it in an object, I am facing an issue where trying to print it using object properties shows undefined values. Here is a snapshot of my output: view image here Snippet of my code: this.documentService.getD ...

Sort the inner array within an outer array

const dataArray = [ { id: 1, title: "stuffed chicken is tasty as anything", picture: "./img/chicken.jpg", tags: ["oooo", "tasty", "stuffed"] }, { id: 2, title: "noodles with shrimp and salad", ...

Angular is not programmed to automatically reflect updates made to my string array

let signalRServerEndPoint = 'https://localhost:44338'; this.connection = $.hubConnection(signalRServerEndPoint); this.proxy = this.connection.createHubProxy('MessagesHub'); this.proxy.on("ReceiveMessage", (message) => { ...

Leveraging Angular's Observables to Defer Multiple API Requests within a Specified Timeframe

In my Angular 4 app, I have a setup like this (for illustration purposes, I've omitted some code) @Injectable() export class SomeService { constructor( private http: Http ) { } get(id: number) { return this.http.get( ...

Simulated custom error response object jasmine-Angular

Within the HTTP service, there is a single function designed to manage all HTTP errors, taking custom objects and displaying errors based on specific conditions. This is an example of the service function: get(path: string, params: HttpParams = new Http ...

An expression must be a modifiable lvalue in order to set an element within a dynamic array consisting of fixed-length arrays

Within my C++ program, I am working with a dynamic char array where each element is a fixed-size array with a length of MAX_LINE_SIZE. This is how I have set up the array inside my main function: char (*text)[MAX_LINE_SIZE] = nullptr; The goal is for thi ...

Using Typescript file for importing configurations instead of relying on json files dynamically

Let me give you some context: Our team is working on creating AWS CDK modules using Typescript (just so you know, I'm not very experienced in TS). One of the modules we're developing is for managing container-based applications that developers c ...

JavaScript transforming an array into a counter

I am seeking a way to transform a one-dimensional array into a frequency dictionary in JavaScript. The array elements should serve as keys, while their frequencies act as values. Take, for example, the Python script below, which generate a list of 1024 ra ...

When attempting to utilize TypeScript with Storybook, Jest may encounter an error stating, "Incompatible types for property 'id'."

Currently, I'm exploring the use of stories in my unit tests with Jest + RTL to reduce redundancy. However, I've encountered an error stating "Types of property 'id' are incompatible" when passing arguments that are also used in my stor ...

Tips for displaying an array within a table data cell during a while loop

I've encountered this code snippet: $result7 = mysqli_query($conn, $sql7); $resalm = mysqli_query($conn, $contalm); $p = array(); while($row_alm = mysqli_fetch_array($resalm)) { $p[] = $row_alm['nome']; } while($rows_cursos7 = mysqli_fet ...

M.E.A.N - Suite for setting up and defining backend boundaries consisting of MongoDB, Express.js, Angular2, node.js

Seeking knowledge on how the frameworks and platforms Angular 2 and Express.js collaborate in the 'mean' approach is my main query. I am interested in understanding where the client-side ends and the server-side begins. After delving into this t ...

PHP: Check if an array contains values that begin with a specific value

I've created a function designed to search through an array and find values that start with the specified second parameter: public static function arrayContainsValueStartingBy($haystack, $needle) { $len = strlen($needle); foreach ($hays ...

The issue with npm run build may be caused by a compatibility issue between TypeScript and lodash

Currently using typescript version 4.5.2 and lodash version 4.17.21 Running the command npm run build will trigger tsc && react-scripts build The following errors were encountered during the build process: node_modules/@types/lodash/common/objec ...

Adjust the size of the cursor

Currently, I am in the process of creating a drawing application akin to Paint or Sketchpad. One issue I have encountered is the inability to resize the cursor based on the line width of the pencil I am using. The workaround I have discovered involves usin ...

Tips for assigning multiple Angular2 variables in Jquery on change

I am having trouble assigning more than one variable in jQuery within Angular2. Here is my current code: jQuery('.source-select').on('change',(e) => this.updateForm.value.sources = jQuery(e.target).val().split('--')[0]); ...

Exploring Several Images and Videos in Angular

I'm experiencing a challenge with displaying multiple images and videos in my Angular application. To differentiate between the two types of files, I use the "format" variable. Check out Stackblitz export class AppComponent { urls; format; on ...

Waiting for the function to complete within an if statement

When attempting a test, I encountered an issue where the function does not wait for the database request to be made. It seems like the function initially returns undefined, and only after the request is completed it returns true or false causing the test t ...