Mapping properties between objects in Typescript: transferring data from one object to another

Here are two different types and an object:

type TypeX = {
  x: number;
  y: number;
  z: number;
};
type TypeY = {
  u: number;
  v: number;
  w: number;
};
initialObject: { [key: string]: TypeX };

The goal is to transfer the properties from an object of type TypeX to an object of type TypeY. Here's what has been accomplished so far.

const finalObject: { [key: string]: TypeY } = {};

Object.entries(initialObject).forEach(([key, value]) => {
  finalObject[key] = {
    u: value.x,
    v: value.y,
    w: value.z,
  } as TypeY;
});

Is there a way to achieve this in TypeScript using a map or reduce function? It would be ideal to avoid assigning {} to finalObject initially.

Answer №1

You have the option to employ Object.fromEntries.

type TypeX = {
    x: number;
    y: number;
    z: number;
};
type TypeY = {
    p: number;
    q: number;
    r: number;
};

declare const oldData: { [key: string]: TypeX };

const newData: { [key: string]: TypeY } = Object.fromEntries(
    Object.entries(oldData).map(([key, value]) => [
        key,
        {
            p: value.x,
            q: value.y,
            r: value.z
        }
    ])
);

Playground Link

To provide further detail, Object.fromEntries functions as a reverse operation of Object.entries, transforming an array comprising [key, value] pairs into an object matching keys with their corresponding values.

In this context, we initially use Object.entries and then utilize a map function to convert each item from [key, value] to [key, newValue], which is subsequently fed into Object.fromEntries.

Please bear in mind that Object.fromEntries was included in ES2019. In cases where your runtime environment lacks ES2019 support, integrating a polyfill like npm:object.fromentries becomes necessary, along with specifying

"lib": ["ES2019"]
or later within your tsconfig.json

The unnecessary type assertion as TypeY has been removed to avoid suppressing errors such as overlooking or misspelling properties defined by TypeY. TypeScript's ability for type inference stands out as one of its key features.

Your inclination towards utilizing map and reduce aligns well with best practices. While map is employed here, reduce was commonly used before the introduction of Object.fromEntries to achieve similar outcomes.

Answer №2

Using lodash's mapValues function is another option available

const initialData = {
  x: { apples: 5, bananas: 10, oranges: 15 },
  y: { apples: 20, bananas: 30, oranges: 40 },
}

function transformData(item) {
  return {
    fruits: item.apples,
    berries: item.bananas,
    citrus: item.oranges
  };
}

const updatedData = mapValues(initialData, transformData);

console.log(updatedData);

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

What is the best way to align a title above menu items within a Material UI app bar when using TypeScript and React?

Check out my current app bar design: app bar image Here is the inspiration for the app bar layout I'm aiming for (title above menu items): inspiration app bar goal This snippet showcases my code: import * as React from 'react'; // More cod ...

The rapid execution of code causing an observable race condition

When exporting a CSV file in my code, I encounter a race condition while trying to modify some data before the export. The issue is that the id gets set correctly, but the number only updates after the method is called a second time. I believe the proble ...

What is the best way to combine TypeScript output while maintaining node import integrity?

Currently, I am combining the results of the typescript compiler using this particular technique. However, this process is causing issues with the imports of relative path modules in Node. The code below compiles and merges successfully; // Group.ts clas ...

Error: Missing npm install -g @angular/cli@latest package in devDependencies section

ng build is causing an issue that The error reads: Unable to Find npm install -g @angular/cli@latest in devDependencies. When I attempt to start the application using npm start, it works fine. However, while trying to build a file, I encounter this er ...

The Redux Toolkit Slice is encountering an issue where it generates the incorrect type of "WritableDraft<AppApiError> when the extraReducer is

I defined my initial state as MednannyAppointments[] for data and AppApiError for error. However, when I hover over state.error or state.data in my extraReducer calls, the type is always WritableDraft. This behaviour is confusing to me. Even though I have ...

How to pass data/props to a dynamic page in NextJS?

Currently, I am facing a challenge in my NextJS project where I am struggling to pass data into dynamically generated pages. In this application, I fetch data from an Amazon S3 bucket and then map it. The fetching process works flawlessly, generating a se ...

When utilizing the catch function callback in Angular 2 with RxJs, the binding to 'this' can trigger the HTTP request to loop repeatedly

I have developed a method to handle errors resulting from http requests. Here is an example of how it functions: public handleError(err: any, caught: Observable<any>): Observable<any> { //irrelevant code omitted this.logger.debug(err);//e ...

What are the steps to extract information from an observable?

Having trouble retrieving data from a request? I've encountered an issue where the data retrieved inside .subscribe in an observable function is returning as undefined when trying to access it outside the function. It's quite frustrating! Here i ...

What are the steps for creating a custom repository with TypeORM (MongoDB) in NestJS?

One query that arises is regarding the @EntityRepository decorator becoming deprecated in typeorm@^0.3.6. What is now the recommended or TypeScript-friendly approach to creating a custom repository for an entity in NestJS? Previously, a custom repository w ...

What is the best way to ensure that the operations are not completed until they finish their work using RX

Is there a way to make RXJS wait until it finishes its work? Here is the function I am using: getLastOrderBeta() { return this.db.list(`Ring/${localStorage.getItem('localstorage')}`, { query: { equalTo: fa ...

Emotion, material-ui, and typescript may lead to excessively deep type instantiation that could potentially be infinite

I encountered an issue when styling a component imported from the Material-UI library using the styled API (@emotion/styled). Error:(19, 5) TS2589: Type instantiation is excessively deep and possibly infinite. Despite attempting to downgrade to typescript ...

Searching for TypeScript type definitions for the @Angular libraries within Angular 2

After updating my application to Angular2 v2.0.0-rc.1, I am encountering TypeScript compile errors and warnings when webpack bundles my application. These messages appear for any @angular packages referenced in my TypeScript source files: ERROR in ./src/a ...

Encountering a problem with the 'string' parameter when using TypeScript

I keep encountering the following error message: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ barkingRoadProject: string[]; }'. No index signature with a paramet ...

Is it possible to combine TypeScript modules into a single JavaScript file?

Hey there, I'm feeling completely lost with this. I've just started diving into Typescript with Grunt JS and I could really use some assistance. I already have a Grunt file set up that runs my TS files through an uglify process for preparing the ...

Fire the BehaviorSubject with the identical value following a mutation

I am working with a BehaviorSubject where I have to make changes through mutation (for reasons beyond my control). I need to trigger the BehaviorSubject for subscriptions whenever there are changes. Is there another approach I can take instead of using: ...

Can anyone provide guidance on incorporating lodash into an Ionic 2 project?

Recently, I began diving into a new project that involves Ionic 2. TypeScript is still fairly new to me, and I've been brainstorming ways to integrate lodash into my project. Have any of you tackled this before and can offer guidance on how to achiev ...

The property functions normally outside the promise, but is undefined when within the promise context

I am currently working on filtering an array based on another array of different objects but with the same key field. Although I have made some progress, I keep encountering errors that I am unable to resolve. @Component({ selector: 'equipment&ap ...

Prompt user to save changes or cancel before closing modal (if closed by pressing ESC or clicking the backdrop)

When I manually close the modal, everything works fine. I just create a prompt and only call the BsModalRef.hide() method when the prompt (sweetalert) is closed. However, when the modal is closed using the ESC key or click-outside events provided by Boots ...

Conceal the Angular Material toolbar (top navigation bar) automatically when scrolling downwards

In my Angular application, the main navigation consists of a standard toolbar positioned at the top of the page. My goal is to have this navigation bar smoothly scroll up with the user as they scroll down, and then reappear when they scroll back up. I at ...

ESLint warning: Potentially risky assignment of an undetermined data type and hazardous invocation of an undetermined data type value

Review this test code: import { isHtmlLinkDescriptor } from '@remix-run/react/links' import invariant from 'tiny-invariant' import { links } from '~/root' it('should return a rel=stylesheet', () => { const resp ...