Generate a versatile Union type featuring a mapped property

I am currently working with different types of data

enum DataTypes {
  Email = 'email',
  Checkbox = 'checkbox',
}

type DataTypeValues = {
  [DataTypes.Email]: string;
  [DataTypes.Checkbox]: boolean;
};

type Type1<T extends DataTypes> = { type: T } & {
  [key in T]: DataTypeValues[T];
};

type Type2 = Type1<DataTypes.Email | DataTypes.Checkbox>

In the given example, Type2 looks like this:

{
  type: 'email' | 'checkbox',
  email: string,
  checkbox: boolean
}

However, I actually need it to be structured as follows:

{
  type: 'email',
  email: string
} | {
  type: 'checkbox',
  checkbox: boolean
}

I have extensively studied TypeScript documentation on typings and found some interesting information, but nothing that addresses my specific scenario.

Is there a way to achieve the desired structure, or should I consider modifying my base types (DataTypes, DataTypeValues)?

Answer №1

Imagine creating a type that encompasses all possible values:

type AllValues<T extends Types> = {
  [key in T]: {
    kind: key,
    info: MappedInfo[key]
  }
}

type FullType = AllValues<Types.Email | Types.Checkbox>

In this case, FullType looks like this:

{
  email: {
    kind: 'email',
    info: string
  },
  checkbox: {
    kind: 'checkbox',
    info: boolean
  }
}

You can then use a generic to iterate through this map and convert it into a union type:

type AllValues<T extends Types> = {
  [key in T as string]: {
    kind: key;
  } & {
    [prop in key]: MappedInfo[key];
  };
}[T];

As a result, FullType transforms into:

({
    kind: Types.Email;
} & {
    email: string;
}) | ({
    kind: Types.Checkbox;
} & {
    checkbox: boolean;
})

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

Error message displaying Angular Service not able to be injected into component: StaticInjectorError in AppModule

I'm currently attempting to inject a SpotifyService service into a SearchComponent component, where the service requires Http as a parameter. Below is my module setup: @NgModule({ imports: [ BrowserModule, FormsModule, RouterModule ], decla ...

Disable TS4023 error in TypeScript: Unable to name external module "xyz"

//custom-slice.js import { createCustomSlice } from '@my/data-toolkit'; /* ***********************For Managing all the divisions data****************************** */ export const divisionDataSlice = createCustomSlice({ name: 'divisionda ...

The JSON.stringify method in TypeScript/JavaScript does not align with the json-String parameter or request body in a Java controller

Currently, I am utilizing jdk 1.8 and have a rest endpoint in my Java controller: @PostMapping("/filters") public ResponseEntity<StatsDTO> listWithFilter( @RequestBody(required = false) String filter ) { try { ............... } } A test sn ...

What is the counterpart of $.isEmptyObject({}) in Typescript for checking if an object is

Is there a formal method for testing an Object (response from server) to see if it is empty? Currently, I am using jQuery to accomplish this. this.http.post(url, data, {headers: headers}).then( result => { if (!$.isEmptyObject(result ...

Translate array into object with correct data types (type-specific method)

Welcome In our project, we have implemented attributes support where each attribute acts as a class. These attributes include information on type, optionality, and name. Instead of creating an interface for every entity, my goal is to automate this proces ...

Error message in Visual Studio 2017: Identical name 'URLs' declared twice in

In our Visual Studio 2017 project, we have multiple TypeScript files that define a URLs class. Each file contains different implementations of the class to change site URLs based on the specific use case: customer/urls.ts namespace Portal { export cl ...

Stop the interval once the route is altered in Angular 2

After initiating a timer within an Angular 2 component located inside a router outlet, I encounter a problem when switching routes. The timer continues to run even after leaving the route. How can I ensure that the timer is properly stopped upon route ch ...

Can someone explain why the Next 13 API route is showing up as empty?

I am currently working with Next 13 and I am attempting to create a simple API route. My goal is to have a: "hi" returned when I visit localhost:3000/api/auth. Despite not encountering a 404 error or any errors in the terminal or console, I can&a ...

Enhancing component and view functionality in Angular

Recently, I started working on Angular 11 and encountered a simple yet challenging question. Despite my best efforts, I have been unable to find a suitable answer. In an attempt to utilize Object-Oriented Programming (OOP) concepts within Angular, I create ...

Exploring the possibilities of developing WebComponents within Angular using TypeScript

My Angular application was originally created using the default method with ng new project-name". However, for performance reasons, I had to incorporate single standard WebComponents. The JavaScript code associated with these components is stored in a ...

Implementing try-catch logic for element visibility in Playwright using TypeScript poses limitations

There is a specific scenario I need to automate where if the title of a page is "Sample title", then I must mark the test as successful. Otherwise, if that condition is not met, I have to interact with another element on the page and verify if the title ch ...

Updating the checkbox status in Angular when the radio button value is changed

I need help with a feature where all the checkboxes are checked based on the value of a radio button, and vice versa when an unchecked radio button is clicked. I have tried to implement this functionality using the following code but have not been successf ...

Updating Angular 5 Views Dynamically Using a While Loop

I am facing an issue in my app where I have a progress bar that updates using a while loop. The problem is that the view only updates after the entire while loop has finished running, even though I am successfully changing the update progress value with ea ...

The Angular7 counterpart of the C# attribute decorator

I'm working with an API method that has an Authorize attribute to verify permissions. [Authorize(ReadIndexes)] public async Task<IActionResult> GetIndexes () { ... } Is there a similar way in Angular to implement permission checks so the API ...

Automatically adjust the model input (Signal) based on the parent and respond to any alterations in the children

Within my Angular 16 application, I have a parent component that passes a plain JavaScript object (myObj) to a child component, where it is treated as a model<MyObj>. <!-- parent.component.html --> <app-children [myObjModel]="myObj&qu ...

Clear the input field once an item has been successfully added to the array

I'm working on a CRUD application using an array. Once I add an item to the array, the HTML input field doesn't clear or reset. I've searched online but couldn't find a reset method in Angular. How can I clear the input field after addi ...

Deriving values in Typescript based on a subset of a union for conditional typing

Can someone provide assistance with type inference in TypeScript to narrow a union based on a conditional type? Our API validates a set of parameters by normalizing all values for easier processing. One parameter can be either an array of strings or an ar ...

Error encountered in Angular 2 with RXJS Observable: Unable to call function catch() on this.http.get(...).map(...) due to TypeError

Everything was running smoothly with my Service until today, when I encountered the following error: TypeError: this.http.get(...).map(...).catch is not a function. Upon debugging the code, it crashes at the catch method. import { Test } from "./home.c ...

Developing a user interface that filters out a specific key while allowing all other variable keys to be of the identical type

As I dive deeper into the TypeScript type system, I find myself grappling with an interface design query. Can anyone lend a hand? My goal is to craft an interface in TypeScript where certain object keys are of a generic type and all other keys should be o ...

Encountering issues while attempting to utilize pdf2json in a TypeScript environment

When attempting to import pdf2json (3.0.1) into my Node project using TypeScript, I encountered the following error: "Could not find a declaration file for module 'pdf2json'." I also tried installing @types/pdf2json for TypeScript but found tha ...