Steps for transitioning from a mapped type to a discriminated union

Forgive me if this question has already been posed. I made an effort to search for a solution, but it seems I may not be using the correct terms.

The issue arises with this particular structure. It involves a simple mapped type:

type Mapped = {
  square: {
    size: number;
  };
  rectangle: {
    width: number;
    height: number;
  };
};

Next, I have a type that is attempting to create a union:

type Unionize<T> = {
  name: keyof T;
  data: T[keyof T];
};

type Out = Unionize<Mapped>;

This results in the following type:

type Generated = {
  name: "square" | "rectangle";
  data: {
    size: number;
  } | {
    width: number;
    height: number;
  };
}

However, what I truly desire is this, as it would allow me to utilize discriminated unions to deduce and verify data properties.

type Wanted = {
  name: "square";
  data: {
    size: number;
  };
} | {
  name: "rectangle";
  data: {
    width: number;
    height: number;
  };
}

Answer №1

Instead of creating the name and data types separately with keyof T, you can first use a mapped type to combine the appropriate name and data for each key in T and then access that using keyof T to form the union.

type CombineKeys<T> = {
  [K in keyof T]: {
    name: K;
    data: T[K];
  }
}[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

What is the correct version compatibility matrix for Expo, NPM, Node, React Native, and TypeScript?

Currently, I am in the process of setting up React Native with TypeScript. Here are the steps I followed: npx react-native init MyApp --template react-native-template-typescript I made sure to install TypeScript as well: npm install -g typescript ' ...

Utilizing Regex to Authenticate a CAGE Code

Our task is to create a RegEx pattern that can accurately validate a CAGE Code A CAGE Code consists of five (5) positions. The code must adhere to the following format: The first and fifth positions must be numeric. The second, third, and fourth position ...

Utilizing TypeScript 2's Absolute Module Paths

The issue at hand: I am facing a challenge with relative module paths and have attempted to resolve it by configuring the baseUrl setting in my tsconfig.json file. Despite my efforts, I keep receiving an error indicating that the module cannot be found. I ...

Typescript: Dynamic return type determined by argument properties

I have a function that should return two different types based on its argument props. interface IPaginateParams { perPage: number; currentPage: number; isFromStart?: boolean; } interface IWithPagination<Data, TParams extends IPaginateParams = IPa ...

Trouble with querying NG elements using "queryAll(By.css)" in Angular and Jasmin unit testing

I've encountered an unusual problem that needs to be resolved for me to successfully complete a unit test for a project I'm currently engaged in. Here is what my unit test currently looks like: it('should display the navbar list', ...

What are the main challenges in resolving dependencies and implementing best practices when it comes to updating an outdated Angular NodeJS

After several months away, I am now faced with the challenge of updating and maintaining an out-of-date angular project. Seeking advice from experienced developers on how to tackle this situation. Previously, I used NPM update or upgrade commands to keep ...

In a situation where Typescript fails to provide enforcement, how can you effectively indicate that a function is not defined for specific value(s)?

If I were to utilize Typescript to create a function called mean that calculates the mean of an array of numbers, how should I handle the scenario where the array is empty? Enforcing that an array must be non-empty can be inconvenient, so what would be th ...

Concealing tab bars on Ionic 2 secondary pages

In my Ionic Bootstrap configuration, I have the following setup: { mode: 'md', tabsHideOnSubPages: true } However, despite having this setting in place, the tabs still appear on some sub-pages. It seems to be happening randomly. Is there ...

Utilizing an Angular component for multiple purposes

For my Angular app, which is component-based and uses Angular version 1.5.5 with TypeScript, I have a header component that includes a country dropdown. This header component is used across multiple pages. However, when a country is selected from the dropd ...

What is the best way to categorize a collection of objects within a string based on their distinct properties?

I am working with an array of hundreds of objects in JavaScript, each object follows this structure : object1 = { objectClass : Car, parentClass : Vehicle, name : BMW } object2 = { objectClass : Bicycle, parentClass : Vehicle, name : Giant } object3 = { ob ...

How can Enums be utilized as a key type for transmitting properties in Vue?

After stumbling upon a helpful method on Stack Overflow that demonstrated how to use an enum to define an object, I decided to implement this in my Vue project. export enum Options { randSize = 'randomSized', timer = 'showTimer', ...

Tips for transferring an excel file to a C# controller from Angular 4 within Visual Studio 2017

I'm working on a web application where I need to import an Excel file and send it to the server-side controller. On the server-side, I am utilizing EPPlus for this task. Can anyone provide guidance on how to accomplish this? I would greatly appreci ...

Using Typescript: accessing all properties from a specified type while excluding one

Currently working in React, I am interested in extending my type from another, with the exception of some props. This is how I want to approach it : import React from 'react'; import { withTheme } from 'styled-components'; import SvgBa ...

The process of HTML compilation is halted due to the unexpected presence of the forbidden 'null' data type, despite the fact that null cannot actually be a valid value in

Encountering an issue with my HTML code, where the compiler stops at: Type 'CustomItem[] | null | undefined' is not compatible with type 'CustomItem[] | undefined'. Type 'null' cannot be assigned to type 'CustomItem[] ...

Utilizing JavaScript variables imported from an external library in Next.js: A Guide

I am currently working on a Next.js with Typescript website and I am in the process of adding advertisements. The ad provider has given me instructions to embed this JavaScript code on my site: <script src="//m.servedby-buysellads.com/monetization. ...

The SrollToTop function is ineffective when used with a component in Ionic 6/Angular

Recently, I implemented a fabbutton feature that allows users to scroll to the top of a page with just one click. Initially, I tested this functionality without using it as a component, and everything worked perfectly. However, now I want to turn this fabb ...

Automatically select a value in MUI AutoComplete and retrieve the corresponding object

I recently set up a list using the MUI (v4) Select component. I've received a feature request to make this list searchable due to its extensive length. Unfortunately, it appears that the only option within MUI library for this functionality is the Au ...

Dialog box obscuring PrimeNG dropdown menu

I'm working on an Angular2 app that utilizes PrimeNG components. My issue arises when trying to include a dropdown inside a dialog box. Despite my implementation, the dropdown ends up being cut off due to the constraints of the dialog box, as visible ...

When using Angular version 13 alongside rxjs 7.4 and TypeScript 4+, an issue arises with the error message: "Declaration file for module 'rxjs' not found"

Currently embarking on a new Angular app using V13 and rxjs7.4, I encountered the error shown above when trying to import: import { BehaviorSubject } from 'rxjs'; Initially, I attempted to address this by creating a typings.d.ts declaration as s ...

Utilizing Mongoose RefPath in NestJS to execute populate() operation

After registering my Schema with mongoose using Dynamic ref, I followed the documentation available at: https://mongoosejs.com/docs/populate.html#dynamic-ref @Schema({ collection: 'quotations' }) export class QuotationEntity { @Prop({ r ...