associating an enum with a specific key value using generics

Imagine having a basic enum

enum MyEnum {
  a,
  b,
  c
}

Converting the enum into key-value pairs is straightforward:

type A<V> = { [k in MyEnum]: V };

const testA: A<string> = { 
  [MyEnum.a]: '',
  [MyEnum.b]: '',
  [MyEnum.c]: ''
};

The issue arises when attempting to use the enum as a generic type:

type B1<T, V> = { [k in T]: V } // this won't work
const testB: A<MyEnum , string> = { ... } // example

I've tried various approaches on this play-ground

There are some related questions (listed below) but I still believe that if the first option (

type A<V> = { [k in MyEnum]: V };
) works, the other options should as well (type B1<T, V> = ).

Mapping Enum to Type of keys or values

is-it-possible-to-allow-literal-string-values-with-typescripts-enum-type

Answer №1

The error message regarding the code snippet

type B1<T, V> = { [k in T]: V }
states
There is an issue where 'T' is not compatible with 'string | number | symbol'.
. This can be resolved by introducing a constraint to T:

type B<T extends PropertyKey, V> = { [k in T]: V }

(utilizing the in-built

type PropertyKey = string | number | symbol
)

Now, you can supply the enum to B as a generic parameter:

const testB: B<MyEnum, string> = {
  [MyEnum.a]: 'aa',
  [MyEnum.b]: 'bb',
  [MyEnum.c]: 'cc'
};

TypeScript playground

Alternatively, following the suggestion by Alex Wayne, you can skip declaring B entirely and directly use the predefined Record type. Its definition is

type Record<K extends keyof any, T> = {[P in K]: T}

which is essentially equivalent to B, as keyof any equals to string | number | symbol, just like PropertyKey.

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

declaration of function interface and property that cannot be modified

After reviewing some new TypeScript code, I encountered a part that left me puzzled. interface test { (a: number): number; readonly b: number; } While I understand that (a:number): number signifies a function where the argument is a:number and the ret ...

The references to the differential loading script in index.html vary between running ng serve versus ng build

After the upgrade to Angular 8, I encountered a problem where ng build was generating an index.html file that supported differential loading. However, when using ng serve, it produced a different index.html with references to only some 'es5' scri ...

Utilizing a library that solely enhances the functionality of the Array object

I have a library with type definitions structured like this: declare global { interface Array<T> { addRange<T>(elements: T[]): void; aggregate<U>(accumulator: (accum: U, value?: T, index?: number, list?: T[]) => an ...

You cannot assign multiple properties with the same name to an object literal

I am facing an issue with two validator functions in my TypeScript file. The first validator checks if a user enters a new password same as the old one, displaying an error if so. The second validator ensures that "new password" and "confirm password" must ...

Consistently scaling the Embla carousel slides for a seamless presentation experience

In my current project, I am utilizing Embla Carousels and aiming to incorporate a smooth slide scaling effect as users scroll through. The idea is for slides to enlarge the closer they get to the left edge of the carousel container, then decrease in size r ...

Tips for altering a key within a tree-view:

I am working with a potentially infinite tree-view array: type Tree = { id: number; name: string; email: string; children: Tree[]; }; const tree: Tree[] = [ { id: 1, name: 'Truck', email: '@mail', children ...

Acquire request data prior to exiting function in React

I am working on a NextJS application that utilizes axios for making requests to a backend API, which requires an authentication token. To handle this, I have implemented a function that retrieves the auth token and stores it in a variable at the module-lev ...

Issue [ERR_MODULE_NOT_FOUND]: The module 'buildapp' could not be located within buildserver.js

I am currently working on a node project using typescript. The project's structure is organized in the following way: --src |-- server.ts |-- app.ts --build |-- server.js |-- app.js In server.ts: import { app } from &q ...

Exploring the Behavior of Subscribing to a Shared Service in Angular

Within my Angular project, I have implemented a service to share variables across different components. The code for this service is as follows: import { Injectable } from "@angular/core"; import { BehaviorSubject } from "rxjs"; @Injectable() @Injectable( ...

`Why are some options missing from the "New Item" feature in Visual Studio?`

Recently, I started a Cordova project using Visual Studio 2015. To my surprise, when I attempt to add a new item by right-clicking, I am presented with only a limited number of options. For example, I wanted to add a "TypeScript json config file" (known as ...

Creating adaptable rows and columns with Angular Material's data table feature

My approach to rendering dynamic rows and columns using a basic table was successful: <tbody> <tr *ngFor="let row of data"> <td *ngFor="let val of row"> {{ val }} </td> </tr> </tbody> </ ...

`Can incompatible Typescript types be allowed for assignment?`

Currently, I am faced with the challenge of sharing type definitions between my server and front-end. These definitions are stored in a separate npm package that both installations utilize. The issue arises on the front-end where variables containing Objec ...

ERROR: Unhandled promise rejection: Unable to find a matching route for URL Segment 'main/knowledge-base'

After setting up dynamic routing for my Angular 6 application, I encountered an error when clicking on a link (for example, 'knowledge base') that stated: core.js:1673 ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segme ...

Creating a TypeScript generic record with specified keys

I need to validate in TypeScript whether an object contains the specified keys (from SingleShopColumns or MultishopColumns) and has a validations property that is an array of strings. I am using Record and generics, but any simple method of representing t ...

Typescript-powered React component for controlling flow in applications

Utilizing a Control flow component in React allows for rendering based on conditions: The component will display its children if the condition evaluates to true, If the condition is false, it will render null or a specified fallback element. Description ...

The @input field is failing to show the value entered by the user

I'm having trouble with my dynamic reactive form, as the value is not showing up <div *ngFor="let deliveryAcross of (deliveriesAcross | async)!; let i = index;"> <app-delivery-across [index]="i" [deliveryAcross]= ...

What is the process of converting a byte array into a blob using JavaScript specifically for Angular?

When I receive an excel file from the backend as a byte array, my goal is to convert it into a blob and then save it as a file. Below is the code snippet that demonstrates how I achieve this: this.getFile().subscribe((response) => { const byteArra ...

Error in Angular SSR: Build failed due to project reference without "composite" setting set to true

Currently facing an issue while developing an Angular App with SSR. When using npm run build:ssr, the following errors are displayed: ERROR in [...]/tsconfig.json [tsl] ERROR TS6306: Referenced project '[...]/tsconfig.app.json' must have se ...

Creating custom typings in a typings.d.ts file does not address the issue of importing a JavaScript library

I'm attempting to integrate the Parse-server JS sdk into an angular 8 application, but no matter what approach I take, I encounter errors. Here is what I have tried: Creating custom typings.d.ts files with declare var parse: any; Installing the @ty ...

The function 'transformArticles' is not recognized as a property of the object 'Article'

I'm encountering an issue with Typescript that I need help understanding. In my code, I have a route where I am importing a class called Article like this: import { Request, Response } from "express"; const appRoot = require("app-root-path"); import ...