Mapping Objects to Types in Typescript: A Comprehensive Guide

Imagine I have a data object and I want to create a versatile mapper function that can be used for all types without having to instantiate a new class each time, like this:

this.responseMapper.map<CommentDTO>(data);

The goal is to take the properties from the specified type and map the data accordingly. Here's what I've attempted:

public map<T>(values: any): T {
    const instance = new T();

    return Object.keys(instance).reduce((acc, key) => {
        acc[key] = values[key];
        return acc;
    }, {}) as T;
}

However, using new T(); results in an error:

'T' only refers to a type, but is being used as a value here.

What would be the correct approach to achieve this?

Answer №1

In order to utilize the method effectively, you must provide the type constructor as an argument. Generics are removed in Typescript at runtime, making T unknown. It is advisable to restrict the input for values to only accept members of type T, which can be achieved using Partial<T>

public map<T>(values: Partial<T>, ctor: new () => T): T {
    const instance = new ctor();

    return Object.keys(instance).reduce((acc, key) => {
        acc[key] = values[key];
        return acc;
    }, {}) as T;
 }

Example of Usage:

class Data {
    x: number = 0; // Initialization is necessary otherwise keys will not return 'x'
}

mapper.map({ x: 0 }, Data)

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

Why is the image auto-swapping script failing to display images frequently?

I have a script that is currently running to rotate between two different logos on my webpage. What I am attempting to achieve is for the page to load and then seamlessly transition from one image to the other without any blank space. Below is the code I ...

Oops! The provided value for the argument "value" is not a valid query constraint. Firestore does not allow the use of "undefined" as a value

I encountered an error while exporting modules from file A and importing them into file B. When running file B, the error related to Firebase Cloud Firestore is displayed. const getMailEvents = (startTime, endTime) => { serverRef = db.collection("Ma ...

The functionality of Dnd-kit nested is functioning properly, however, one specific component is unfortunately

Currently, I am dealing with a two-dimensional array that results in two nested dnd-kit drag and drop fields. The nested dnd functions correctly; however, the first one sorts items when moved without any animations (even when moving my div). Below is the ...

A guide on incorporating Google authentication into Vue.js with the use of TypeScript and the component-based syntax

Currently, I am in the process of integrating Google authentication into my Vue.js front end. The project was initialized using CLI with TypeScript and component style syntax enabled, alongside other configurations. Additionally, there is a backend web ser ...

`Getting Started with TypeScript in an ASP.Net MVC Application`

Due to certain reasons, we have decided to begin our project with TS rather than JS. We are facing issues with the variables set in the MVC Views, which are established by the Model of each View. For example, tes.cshtml: @model Testmodel <script> ...

From traditional relational databases to MongoDB/Mongoose database design

Recently, I ventured into using mongoDB and mongoose for a new node.js application. Coming from a background of relational databases, I find it challenging to adjust to the mongoDB/noSQL approach, particularly concerning denormalization and the absence of ...

Steps for disabling and collapsing an individual header on the JQuery Accordian

Looking to adjust the behavior of 4 headers in accordions? Specifically, you want to collapse and disable only the first header out of the set. Here's how: $("#ExpandCollapse").accordion({ active: false, collapsible: true }); To ...

Look for duplicate values in an array, retrieve the value, and determine the frequency

I've populated an array with a random number of strings. var array = ["car", "plane", "plane", "car", "car"]; I want to access the values in the Array and count how many times each one has been added. For example: var a = "car"; var aCount = 3; var ...

Is it possible to extend an Angular component and then use the base component in an ngFor loop?

Can Angular components be extended? And if so, is it possible to create a list of diverse components (using an ngFor loop) that all extend a common base component? For instance, could a custom menu bar display various types of menu items, such as dropdown ...

Storing canvas data retrieved with the toDataURL function as an image on disk using JSF

I used SVG and Javascript to create an image, but now I need to figure out how to let users save it. How can I send this image to a bean and save it? Here's the code: <script> var svg = $('#map').html().replace(/>\s+/ ...

What steps can be taken to resolve an error encountered when attempting a dynamic data POST request from the body

Whenever I attempt the post method to fetch data on Postman and store it in a local MongoDB database, I encounter an error. The error message indicates a bad request with a status code of 400. *The following is app.js: var express = require('express& ...

Using TypeScript with Selenium

What are the benefits of utilizing Selenium with Typescript in comparison to Selenium with Java? In what ways can Selenium+Typescript automate certain types of web applications that Selenium+Java cannot, and why is this the case? ...

What's the best way to combine the data from two different Instagram APIs?

Looking to display Instagram images on a webpage using UserName and Tags. Despite searching for an API that can meet my needs, I haven't found one that allows me to: Show Images based on User Account Show images based on Tags (Single or multiple) ...

How come my jQuery ajax request is successful but the $_POST array remains empty?

Here is my first query on this forum, please be patient with me: The code snippet for my ajax request is: <script> $.ajax({ type:"POST", url:"http://localhost/folder/something.php", data: { BuildingName:'Jacaranda'}, success: function(da ...

Fields that have been loaded are not initialized within the supplementary function

Two functions are used to load components for a page and save them in two fields - representatives and allUsers. An additional function, subtractSets(), is then used to modify the loaded data slightly. The issue arises when these fields (representatives ...

How can I update the state with the value of a grouped TextField in React?

Currently working on a website using React, I have created a component with grouped Textfields. However, I am facing difficulty in setting the value of these Textfields to the state object. The required format for the state should be: state:{products:[{},{ ...

Transform a group of objects in Typescript into a new object with a modified structure

Struggling to figure out how to modify the return value of reduce without resorting to clunky type assertions. Take this snippet for example: const list: Array<Record<string, string | number>> = [ { resourceName: "a", usage: ...

After making an Ajax call using AngularJS in a PHP file, I expected to receive only a success or fail message. Instead, I received the entire HTML page code along

After making an Ajax call using AngularJS in a PHP file, I expected to receive only a success/fail message. However, I ended up receiving the full HTML page code along with tags. Here is my AngularJS code: $http.post('ajax_Location.php',{ &apos ...

Issue: Unable to assign type 'FormDataEntryValue' to type 'string'. Type 'File' cannot be assigned to type 'string'

After retrieving data from the formData, I need to pass it to a function for sending an email. Error: The error message states that 'FormDataEntryValue' is not compatible with type 'string | null'.ts(2322) definitions.ts(119, 3): The e ...

JQuery grid pagination bar mysteriously missing

I'm having an issue with a Jquery grid that is built on an HTML table. I've properly configured the grid properties, including implementing pager functionality with a page size of 10. However, I am unable to see the page up and page down buttons ...