Dynamically change the properties of an interface in TypeScript

Is there a way to dynamically wrap each property in an interface with a generic type?

I have several interfaces defined in a library that I cannot modify by adding generics. One of the interfaces in the library is shown below as an example.

interface Original {
    a: string;
    b: number;
    c: boolean;
}

I also created my own generic type for displaying values in the interface, such as SVG icons and units. Here is the generic interface I made:

interface GenericInterface<V> {
    value: V;
    units: string;
    errorMsg?: string;
    icons: ReactElement<any>;
}

My goal is to wrap each parameter in the Original interface with the GenericInterface, resulting in the modified interface below:

interface Modified {
    a: GenericInterface<string>;
    b: GenericInterface<number>;
    c: GenericInterface<boolean>;
}

I've tried the following approach but it results in a union of all parameter types:

type ModifiedGeneric<T extends object, K extends keyof T> = Record<
    K,
    GenericInterface<T[K]>
>;

type Modified = ModifiedGeneric<
    Original,
    keyof Original
>;

This combines all parameter types into one which is not what I want. Is there a solution to achieve the desired output?

Answer №1

According to the advice from jonrsharpe's comment, you can simply utilize a mapped type:

interface Original {
    a: string;
    b: number;
    c: boolean;
}

interface GenericInterface<V> {
    value: V;
    units: string;
    errorMsg?: string;
    icons: React.ReactElement<any>;
}

type ModifiedGeneric<T extends {}> = {
    [key in keyof T]: GenericInterface<T[key]>
}

type ModifiedOriginal = ModifiedGeneric<Original>
// ModifiedOriginal has type
// {
//   a: GenericInterface<string>;
//   b: GenericInterface<number>;
//   c: GenericInterface<boolean>;
// }

Interactive Code Playground

Please note that the second generic parameter is not necessary unless you specifically require it for handling a subset of keyof T.

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

How to grab the content within an input field using Typescript within an Angular 2 framework

I am attempting to implement the functionality discussed in this particular post, but within an Angular2 framework. Essentially, I need to utilize the javascript function .setSelectionRange(start, end); on an input element after a user interacts with a tr ...

The problem with the "typescript-react-apollo" codegen plugin is that it is declaring block-scope variables more than once in the generated

Recently, I embarked on a new project utilizing NextJS with graphql-codegen to auto-generate my apollo-react types from the API. Unfortunately, it seems to be generating duplicate exported variables right from the start, causing a typescript error and hi ...

An issue has occurred with attempting to access the 'phone' property of a null value. This error is at the root of the problem and needs to

I have implemented a function to retrieve all clients from an API: this.ws.getallclients().subscribe( client => { this.client = client.map((clients) => { this.filteredOptions = this.addsale.controls['client_id'].valueChanges. ...

Problem with Angular 2 Typings Paths in Typescript

Currently, I am in the process of learning how to create a Gulp build process with Angular 2 and Typescript. Following the Quick Start guide has allowed me to get everything up and running smoothly. However, I have decided to experiment with different fold ...

Create a .d.ts file for a custom JavaScript file

I am working on an application written in JavaScript and considering incorporating TypeScript for a new feature. Currently, I have a base class defined in JavaScript as shown below: // base.js module.exports = function BaseClass () { // ... ... }; M ...

Eslint is back and it's cracking down on unused variables with no

I've configured eslint to alert me about unused variables rules: { '@typescript-eslint/no-unused-vars': ['error', { args: 'none' }], } Presently, I have a TypeScript class structured like this: import { User } from &ap ...

Updating FormGroup Value in Angular When Value Changes

I am working on a project where I need to dynamically set a value for a formControl within a formGroup based on changes to another formControl in the same formGroup. However, when I attempted to implement this, I encountered an error stating: maximum call ...

Transitioning from click interaction to webpage navigation

I'm feeling really overwhelmed by Typescript. I'm trying to create an event that changes the Google website when a button is clicked. However, when I press the button, the console displays the following error message: [error message on console] D ...

encountered an issue while accessing a FastAPI-based API

While developing a login feature in Next.js, I encountered an issue when making a request to an API created in FastAPI to retrieve a cookie. The problem arises during the fetch operation on the frontend specifically when setting credentials to 'includ ...

Exploring the Record type in Typescript when using React's useContext

I'm currently facing challenges in grasping the concept of record types within a generator function that I am developing for React contexts. Below is the code snippet of my generator function: import * as React from 'react' export type Sta ...

Troubleshooting: Issues with Angular2 compatibility on Safari version 9.1.2

I am encountering an issue with running my angular2 app on Safari 9.1.2. It works fine on all higher versions of Safari as well as other browsers such as Chrome, Firefox, Opera, and Edge. However, when I try to run it on Safari 9.1.2, I receive the followi ...

Function in Typescript that can return multiple data types

I recently started learning about TypeScript and its concepts. During my practice sessions, I encountered a problem that left me puzzled. There is a function named `functionA` which returns an object based on the response received from an API. type Combina ...

Having trouble establishing a connection with SignalR on my backend, it just doesn't seem to work properly

I am currently working on a project where I am using Vue with TypeScript and @microsoft/signalr. My goal is to create a chat feature using SignalR, and on the backend, I am utilizing C# with ASP.NET Core and docker. Here is the code snippet I have impleme ...

Issue with (click) event not being detected on most elements throughout Ionic 4 webpage

BACKGROUND: After working perfectly for some time, all the click events in my Ionic app suddenly stopped functioning. I have two floating action buttons that used to trigger a JS alert popup and open a modal window, but now they are unresponsive. The onl ...

When dealing with ng effects, an undefined value replaces the stream observable

Currently, I am working on a flow that involves adding a new object to another object's collection. This process starts with some domain-related tasks. Initially, I send an object to the backend and upon receiving a callback, I trigger another action ...

Transfer data from current worksheet to fresh workbook in Script Lab

I am exploring how to utilize TypeScript in Script Lab for Excel to duplicate the active worksheet into a brand new workbook. I came across a sample script that duplicates the worksheet within the same workbook, but I am unsure of how to modify it to cop ...

Implementing Formik in React for automatic updates to a Material-UI TextField when blurred

Presently, I am developing a dynamic table where users can simultaneously modify multiple user details in bulk (Refer to the Image). The implementation involves utilizing Material-UI's <TextField/> component along with Formik for managing form s ...

Enhancing Data Retrieval in Next.js: Implementing Typed Requests and Responses with the Fetch API

Context I've been developing a web application using Next.js and a custom Django Python backend, but I am struggling to find an efficient approach for making API requests from my frontend to the backend. My main goal is to centralize the logic for fet ...

Is there a way to retrieve the Windows username without manual input?

Currently, I am working on creating an internal web portal for our organization. The technologies I am using include Angular 5, Java Spring, REST, JDBC, JSON, and MS SQL Server. To ensure seamless authentication on my website, I have implemented a method ...

Tips on preventing pooling in Angular 5

service.ts: // Fetch all AgentLog logs using pooling method getAgentLogStream(): Promise<string> { const url = `${this.testCaseUrl}/logfile`; return Observable .interval(5000) .flatMap((i)=> this.http.get(url).toPromise().then(respons ...