Utilizing a transformer class to convert the data associated with each key into a different format

When defining my initial type First:

type First = {
  a: string,
  b: number
}

I am open to different approaches in implementing the Dictionary type. An alternative dictionary structure could be:

type Dictionary = {
  string: { "stringValue": string },
  number: { "numberValue": number }
}

My main query is how can I create a generic transformation function Transform<T> that will transform the First type into:

type Second = {
  a: { "stringValue"": string },
  b: { "numberValue": number }
}

Unfortunately, I am unable to determine the typeof T, which has made it difficult to perform an indexed access on the Dictionary. While I have considered using a chain of conditional types manually, it seems like a less elegant solution.

type Dictionary<T> = T extends string ? { "stringValue": string } : { "numberValue": number }
type Second = {[Property in keyof First]: FieldValueOf<First[Property]>}

Answer №1

In order to transform string types into {stringValue: string}, you will require a structure similar to your Dictionary type. However, the naming of keys as "string" and "number" does not directly correlate to the types string or number. To address this, it's best to eliminate key labels altogether. Consider the following:

type Mapping =
    [string, { "stringValue": string }] |
    [number, { "numberValue": number }]

The Mapping here is a union of 2-tuples where the first element represents the "from" type and the second element represents the "to" type. While there are alternative ways to represent this mapping (such as {from: From, to: To} instead of [From, To]), this implementation suffices for most scenarios.

To map all properties of a type T with Mapping, the following can be used:

type UseMapping<T> = { [K in keyof T]: Extract<Mapping, [T[K], any]>[1] };

Here, the Extract<T, U> utility type is utilized to identify the member(s) of Mapping whose "from" type aligns with the property type T[K], and subsequently extract its "to" type by indexing into it using the key 1. Let's test it out:

type Second = UseMapping<First>;;
    
/* type Second = {
    a: {
        stringValue: string;
    };
    b: {
        numberValue: number;
    };
} */

Validation successful!

Try code on Playground

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 module within a script in the continuous integration setup of a React application

I've created a module to verify if all the necessary environment variables are properly set in a React application. Here's a simple example of how it works: const getEnvironmentVariable = (key: string): string => { if (process.env[key]) { ...

Troubleshooting Routing Issues with Angular 12 in a .NET Core Application

I'm currently following a guide on building a specific project using Angular 10 with .NET Core Web API and SQL Server functionalities. Interestingly, I decided to use Angular 12 in my environment. The tutorial goes smoothly up until the routing secti ...

Finding the final day of a specific year using the moment library

When it comes to determining the last day of a year, hard-coding the date as December 31st seems like a simple solution. While there are various methods using date, js, and jquery, I am tasked with working on an Angular project which requires me to use mom ...

Changes in the view are delayed due to updating metatags on the DOM in Angular 8

My component is in need of updating the view following an HTTP call. The scenario involves displaying a record after retrieving data from the server. In the HTML file, we have- <mat-spinner *ngIf="loading"></mat-spinner> <span *n ...

Tips for transitioning to TypeScript: Splitting lengthy Revealing Module Patterns into smaller parts

We are in the process of converting some JS code to TypeScript. Our JavaScript files are currently written using Revealing Module Patterns. Here is a simplified version of the pattern: var thing = (function() { var var1, var2; function init() { ...

While running tslint in an angular unit test, an error was encountered stating 'unused expression, expected an assignment or function call'

Is there a method to resolve this issue without needing to insert an ignore directive in the file? Error encountered during command execution: ./node_modules/tslint/bin/tslint -p src/tsconfig.json --type-check src/app/app.component.spec.ts [21, 5]: unuse ...

Tips for properly waiting for an AngularFire2 subscription to complete before executing the subsequent lines of code within Angular2

Having an issue with my Angular2 Type Script code. The goal is to access Questions from a Firebase Database by subscribing to a FirebaseListObserver: this.af.list('/questions').subscribe( val => { this.questions = val console.log(th ...

Jest is raising a TypeError: Unable to access attributes of an object that is undefined (referencing 'getVideoTracks')

When running my unit tests with Jest, I encountered an error: TypeError: Cannot read properties of undefined (reading 'getVideoTracks') Does anyone have any suggestions on how to properly test the following line using Jest? [videoTrack] = (await ...

The Angular 2 Router's navigation functionality seems to be malfunctioning within a service

Currently, I am facing an issue with using Angular2 Router.navigate as it is not functioning as expected. import { Injectable } from '@angular/core'; import { Http, Headers } from '@angular/http'; import { Router } from '@angular/ ...

Customizing your Mui theme with Typescript may lead to unexpected errors

Within my MUI theme, I am aiming to customize the link element as shown below: components: { MuiLink: { defaultProps: { component: LinkComponent, }, }, } However, I encountered the following TypeScript error: Type error: Ty ...

Angular Material table source data not rendering properly

I have successfully displayed dataSource2 (example from Angular library) but I am facing issues rendering my own dataSource variable. Despite making both data sources similar and using the Angular Material library in a consistent manner, I cannot figure o ...

Utilizing Optional Generics in TypeScript

I have created a wrapper for making API calls to a Strapi server. export const api = { post: async<T extends unknown, K>(url: string, body: Partial<T>, jwt?: string): Promise<K> => { try { const result = await ...

Guide on automatically inserting a colon (:) after every pair of characters in Angular

I am looking to automatically insert a colon (:) after every 2 characters in my input field: HTML <input nz-input type="text" appLimitInput="textAndNumbers" name="mac" formControlName="mac" (keydown.space)=&qu ...

A single pledge fulfilled in two distinct ways

My code ended up with a promise that raised some questions. Is it acceptable to resolve one condition with the token string value (resolve(token)), while resolving another condition with a promise of type Promise<string>: resolve(resultPromise); con ...

When attempting to retrieve the current position using "position.coords.latitude", I receive an undefined value

Having recently started with Ionic2, I came across a helpful tutorial that worked flawlessly for me. The tutorial, which can be found at , demonstrates listing nearby places and calculating the distance between these locations and a hardcoded place in the ...

Merge two observables together to create a single observable that emits values from both sources. Only one observable will emit values

I am looking to combine two observables of type T[] obtained from httpservice. I have tried using forkJoin and zip, but they both return an Observable of type [T[], T[]]. However, I want to receive an object of type T[] as shown in the following code snip ...

The production build is encountering an issue with a type error stating that the property 'companies' does not exist on the 'PrismaClient' type, while the local build is successful

Currently, I am working on a nextjs project hosted on Vercel, utilizing TypeScript and Prisma. Here are the versions I am using: "next": "13.0.3" "typescript": "4.9.3" "prisma": "^4.6.1" My local build is successful, but I am encountering a failure on Ve ...

Implement a data filtering functionality in Angular upon clicking a button

I'm currently working with Angular 10 and Angular Material. Within my mat-table, I am displaying data from an array called ELEMENT_DATA. This array includes various properties for each item such as invoice number, category, description, start date, st ...

The concept of class inheritance and the utilization of the "this" keyword in both static and public methods

I'm delving into the depths of class inheritance trying to unravel its mysteries. Although I have some techniques to handle static method typing, I'd like to delve into a common scenario I encounter and explore alternative perspectives. Consider ...

Having difficulty building a react.js application using Visual Studio 2019

Currently, I am following a helpful tutorial on creating a react.js application using visual studio. At this stage, the tutorial instructs me to open the command prompt and enter the following command: webpack app.tsx --config webpack-config.js (I have ...