Create an object with identical keys as another object

I need to create a mapping between two objects.

The first object can have keys of any string type and values of a generic type.

I want to map the second object with the same keys, allowing different types for the values (ideally extracted from the generic). These properties are part of a class, with the first object being passed in the constructor function.

class C {
  ob1: {
    [key: string]: Wrapper<any>
  };
  ob2; // should have the same keys as ob1

  constructor(o?: { [key: string]: Wrapper<any> }) {
    this.ob1 = o;
    // map ob2 from o
  }
}

Answer №1

To tackle this issue, we can transform the C class itself into a generic class with a type parameter T that corresponds to the type of either obj1 or obj2. By utilizing mapped types, we can effectively represent "same keys but different/related values". Here is an example:

type MappedValues<T> = { [K in keyof T]: Values<T[K]> }
class C<T> {
  obj1: MappedValues<T>
  obj2: T;
  constructor(o: MappedValues<T>) { 
    this.obj1 = o;
    this.obj2 = unwrapMap(o); 
  }
}

In the above code snippet, we declare that the type T represents the type of obj2, while obj1 has the type MappedValues<T>, which is a mapped type where each property of obj1 is associated with a Values-version.


Depending on how Values and related types are implemented and declared, like so:

type Values<T> = { value: T };
function createValue<T>(value: T): Values<T> {
  return { value };
}
function extractValue<T>(val: Values<T>): T {
  return val.value;
}
function unwrapMap<T>(x: MappedValues<T>): T {
  return Object.fromEntries(Object.entries(x).map(([k, v]) => [k, extractValue(v)])) as any as T;
}

We can confirm the functionality by testing it out:

const c = new C({ key1: createValue(123), key2: createValue("hello"), key3: createValue(true) });
/* const c: C<{ key1: number; key2: string; key3: boolean;}> */

c.obj1.key1.value.toFixed(); // no errors
c.obj2.key2.toUpperCase(); // no errors

Playground link for more details

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

Deactivate a variable during operation

I have a unique component called book-smart that has the functionality to display either book-update or book-create based on the availability of a BookDto in my book.service. The update feature can be accessed by clicking a button in a table, while the cre ...

Creating a Modal using Typescript with NextJS

Currently, I'm working on creating a modal within my app using NextJS with Typescript. Unfortunately, I've been struggling to eliminate the warning associated with my modal selector. Can someone provide guidance on how to properly type this? cons ...

When using Typescript, the keyof operator for objects may not undergo refinement and can result in error

I've been working on creating a function that validates whether a key in an object is a non-empty string. export const validateRequiredString = <T>( obj: T, key: keyof T & (string | number) ): void => { if (typeof obj[key] !== " ...

Discovering the secrets of monitoring changes in children's length in React

Here is the code I am working with: const container = useRef(); const [items, setItems] = useState(); useEffect(()=>{ setItems(container.current.children.length); },[container.current, container.current.children.length]) return( <div ref={contain ...

Utilize interface as a field type within a mongoose Schema

I am currently working with typescript and mongoose. I have defined an interface like this: interface Task { taskid: Boolean; description: Boolean; } My goal is to create a schema where one of the fields contains an array of Tasks: const employeeSche ...

Efficiently incorporating multiple properties into one in Angular

Within my Angular service, I have defined variables in the following manner: export class MyService { someVariableA = 1; someParams = { someVariableB, otherVariable: this.someVariableA }; } In a component, I update 'someVariableA&a ...

How can I utilize Pinia and TypeScript to set the State using an Action?

I have a Pinia + TypeScript store named user.ts with the following structure: import { User } from 'firebase/auth'; import { defineStore } from 'pinia'; export const useUserStore = defineStore('user', { state: () => ( ...

How to define an index signature in Typescript that includes both mandatory and optional keys

I am on a quest to discover a more refined approach for creating a type that permits certain keys of its index signature to be optional. Perhaps this is a scenario where generics would shine, but I have yet to unlock the solution. At present, my construc ...

Exploring an Angular Real-World Example Application on Github - Resolving the Following Bug

my surroundings. export const environment = { production: false, api_url: 'localhost:3306/api' }; my personal server is at localhost:3306 (MAMP) The instructions provided are to edit src/environments/environment.ts in order to ch ...

Steps to access email template through an Excel web add-in

Currently, I am developing a new addin that aims to extract data from Excel and insert it into a word document. The final step would be attaching this document to an email in Outlook. While I have managed to achieve this using Power Automate, I prefer to ...

Ways to pass functions as properties to a React custom modal?

I'm currently working on a React login page setup. The login functionality is embedded in a Modal using the React-Modal library. When a user presses the login button, data is supposed to be sent to a Custom Modal as props to display a notification win ...

Error code TS7053 occurs when an element implicitly has an 'any' type because a string expression cannot be used to index an empty object

I have implemented a code snippet that sorts items into groups based on their first character. For example, if the array of item looks like this: {name: 'Foo'} {name: 'Bar'} {name: 'Baz'} The expected result should be: B: ...

Angular Group Formation Issue

I keep encountering the following error: formGroup expects a FormGroup instance. Please pass one in. This is how it looks in HTML: <mat-step [stepControl]="firstFormGroup"> <form [formGroup]="firstFormGroup"> And in my Typ ...

It is not possible to access the Angular component using routing capabilities

I'm facing an issue with my Angular routing setup. I have two components, "view-emp" and "edit-emp", but only "edit-emp" is accessible for navigation. When I try to click on the link to navigate to "view-emp", nothing happens and I stay on the home sc ...

Mockery Madness - Exploring the art of mocking a function post-testing a route

Before mocking the process function within the GatewayImpl class to return the 'mockData' payload, I need to ensure that all routes are tested. import payload from './payloads/payloadRequire'; // payload for request import {Gate ...

What steps are involved in compiling a library without using Ivy?

After compiling my library, I navigated to dist/my-library and encountered the following error message: ERROR: Attempting to publish a package compiled with Ivy, which is not permissible. Prior to publishing, delete and re-build the package without us ...

Compilation error occurred when running Angular with mat-form: ngcc encountered an issue while processing [email protected]

Currently dealing with a compile error in a small mat-form example that I created. Unfortunately, I am unable to pinpoint the exact issue causing this error. If you have a moment, please take a look at the code here: https://stackblitz.com/edit/angular-iv ...

Verify whether an object possesses all the attributes of a class in TypeScript

Within my typescript code, I have a class called abc: export class ABC{ public a : any; public b : any; public c? : any; public d? : any; } In one of my functions, I receive an input which is represented as data:any. My goal is to verify i ...

What is the best way to execute an asynchronous request within a CanDeactivateFn guard in Angular?

Here's a strange question I've been grappling with lately. So, I've got this function that essentially creates a custom Alert Window to handle unsaved form data when a user tries to navigate away. It may or may not be triggered depending on ...

Mastering Typescript lookup types - effectively limit the properties included in a merge operation with the Partial type

Exploring lookup types, I'm interested in creating a safe-merge utility function that can update an entity of type T with a subset of keys from another object. The objective is to leverage the TypeScript compiler to catch any misspelled properties or ...