Ways to retrieve the key of an enum based on its value within Typescript

Here's an example of an enum:

export enum Colors {
    RED = "RED COLOR",
    BLUE = "BLUE COLOR",
    GREEN = "GREEN COLOR"
}

Can you help me figure out how to retrieve the enum key based on a specific value? For instance, if I input "BLUE COLOR", I should get back 'BLUE'.

Colors["BLUE COLOR"] triggers an error that says

Element implicitly has an 'any' type because expression of type '"BLUE COLOR"' can't be used to index type 'typeof Colors'. Property 'BLUE COLOR' does not exist on type 'typeof Colors'.

Answer №1

If you need to retrieve the enum key based on its value, you can modify your enum as shown below. This format should work in older versions as well.

For Basic JavaScript:

 enum Colors {
    RED = "RED COLOR",
    BLUE = "BLUE COLOR",
    GREEN = "GREEN COLOR"
}

For .tsx:

 enum Colors {
        RED = "RED COLOR" as any,
        BLUE = "BLUE COLOR" as any,
        GREEN = "GREEN COLOR" as any
    }

For TypeScript (.ts):

enum Colors {
  RED = <any>"RED COLOR",
  BLUE = <any>"BLUE COLOR",
  GREEN = <any>"GREEN COLOR"
}

You can then retrieve the key like this:

Retrieve enum key by value:

let enumKey = Colors["BLUE COLOR"];
    console.log(enumKey);

Output:

https://i.stack.imgur.com/M3b4n.gif

Another method to retrieve enum key by value:

let enumKey = Object.keys(Colors)[Object.values(Colors).indexOf("BLUE COLOR")];

console.log(enumKey);

Output:

https://i.stack.imgur.com/PZpu2.png

Check it out on jsfiddle:

View coding sample on jsfiddle

Note: A new announcement was made on August 25th with TypeScript 4.8. Please take note of it. Read more here.

Answer №3

I have implemented the following function

export function getEnumKeyByEnumValue(myEnum: any, enumValue: number | string): string {
  let keys = Object.keys(myEnum).filter((x) => myEnum[x] == enumValue);
  return keys.length > 0 ? keys[0] : '';
}

Testing with jest

describe('enum', () => {
  enum TestEnumWithNumber {
    ZERO
  }

  enum TestEnumWithString {
    ZERO = 'ZERO'
  }

  it('should correctly retrieve key for enums with number values', function() {
    const key = getEnumKeyByEnumValue(TestEnumWithNumber, TestEnumWithNumber.ZERO);
    expect(key).toBe('ZERO');
  });

  it('should correctly retrieve key for enums with string values', function() {
    const key = getEnumKeyByEnumValue(TestEnumWithString, TestEnumWithString.ZERO);
    expect(key).toBe('ZERO');
  });

  it('should correctly retrieve key by providing corresponding string value', function() {
    const key = getEnumKeyByEnumValue(TestEnumWithString, 'ZERO');
    expect(key).toBe('ZERO');
  });
});

Sharing in case it benefits someone

Answer №4

Enhanced version of getEnumKeyByEnumValue function without utilizing any:

export function retrieveEnumKeyByEnumValue<
  TEnumKey extends string,
  TEnumVal extends string | number
>(myEnum: { [key in TEnumKey]: TEnumVal }, enumValue: TEnumVal): string {
  const keys = (Object.keys(myEnum) as TEnumKey[]).filter(
    (x) => myEnum[x] === enumValue,
  );
  return keys.length > 0 ? keys[0] : '';
}

Answer №5

Give this a shot

enum Shades
{
   CRIMSON = "CRIMSON SHADE",
   INDIGO = "INDIGO SHADE",
   EMERALD = "EMERALD SHADE"
};   

 console.log(Object.keys(Shades)[Object.values(Shades).indexOf('INDIGO SHADE' as unknown as Shades)]);

Answer №6

Enhanced getEnumKeyByEnumValue function with type validations:

enum Colors {
    RED = "RED COLOR",
    BLUE = "BLUE COLOR",
    GREEN = "GREEN COLOR"
}

type ValueOf<T> = T[keyof T];

function getEnumKeyByEnumValue<R extends (string | number), T extends {[key: string] : R}>(myEnum: T, enumValue: ValueOf<T>): string {
  let keys = Object.keys(myEnum).filter((x) => myEnum[x] == enumValue);
  return keys.length > 0 ? keys[0] : '';
}


let enumKey = getEnumKeyByEnumValue(Colors, Colors.RED);

// This line will result in an error: Argument of type '"OTHER COLOR"' is not assignable to parameter of type 'ValueOf<typeof Colors>'.
//let enumKey = getEnumKeyByEnumValue(Colors, "OTHER COLOR");

console.log(enumKey);

https://jsfiddle.net/2ry1u8qb/

Answer №7

I want to make some adjustments to the code:

return Object.keys(ourEnum).find(y => ourEnum[y] === valueOfEnum);

Answer №8

If you want to retrieve enum keys in this way, you can use the following code snippet:

enum Shades {
    LIGHT = "LIGHT SHADE",
    DARK = "DARK SHADE",
    NEUTRAL = "NEUTRAL SHADE"
}

for (let value in Shades) { 
    if (Shades[value] === "DARK SHADE") { 
        console.log(value);
    }
}

Answer №9

While many are discussing runtime solutions, I have a Typescript solution to share:

enum NEW_ENUM {
    ITEM_ONE = 'First Item',
    ITEM_TWO = 'Second Item'
}

// Outcome:
// type FlippedEnum = {
//     readonly "First Item": "ITEM_ONE";
//     readonly "Second Item": "ITEM_TWO";
}
type FlippedEnum = {[F in keyof typeof NEW_ENUM as typeof NEW_ENUM[F]]: F}

// Outcome:
// type EnumValueFromKey = NEW_ENUM.ITEM_ONE
type EnumValueFromKey = typeof NEW_ENUM[FlippedEnum['First Item']]

Start by creating a type that swaps the positions of the keys and values in the enum. (FlippedEnum)

Using typeof with the enum allows indexed access into the keys of the enum as strings. Then, you can retrieve the name of that key using the flipped enum type.

This approach fully supports autocomplete for the value string and more.

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

Combine the values in the array with the input

I received some data from the back-end which is being written to a form, and it's in the form of an array of objects Below is the code snippet: this.companyDetailsForm = new FormGroup({ directors : new FormControl(response?.companyDirectors) ...

Guide to Validating Fields in Angular's Reactive Forms After Using patchValue

I am working on a form that consists of sub-forms using ControlValueAccessor profile-form.component.ts form: FormGroup; this.form = this.formBuilder.group({ firstName: [], lastName: ["", Validators.maxLength(10)], email: ["", Valid ...

Incorporate any enum value into a Typescript interface

I'm working with a Typescript interface export interface MyInterface { valid: boolean; resourceType: MyEnum; message: string; } As well as an enum enum MyEnum { 'a', 'b', 'c' } Is there a way to allow the ...

Tips for properly executing directives in sequential order while using async in Angular 13

I created a standard registration form using Angular and implemented an async directive (UserExistsDirective) to validate if the email is already taken. To manage error messages, I also utilized a second directive (ValidityStyleDirective) which is also use ...

"Optimize Your Data with PrimeNG's Table Filtering Feature

I'm currently working on implementing a filter table using PrimeNG, but I'm facing an issue with the JSON structure I receive, which has multiple nested levels. Here's an example: { "id": "123", "category": "nice", "place": { "ran ...

What is the best way to loop through an array that contains a custom data type

When I declared the type: export interface Type{ id: number; name: string; } I attempted to iterate over an array of this type: for(var t of types) // types = Type[] { console.log(t.id); } However, I encountered the following error message: ...

Incorporating TypeScript into a project originally developed in JavaScript

I'm considering using TypeScript to write code for a JavaScript project. I've come to appreciate the benefits of TypeScript and am especially interested in using it for our AngularJS 1.5 project, which we plan to migrate soon. As I'm new to ...

How can I dynamically insert a variable string into a link tag using React and TypeScript?

I am just starting out with javascript and typescript, and I need to generate a link based on certain variables. I am currently facing an issue trying to insert that link into <a href="Some Link"> Some Text </a> Both the "Some Text" and "Som ...

Implementing strict typing in Twitter widget to eliminate issues with accessing members

I'm struggling to properly type my Twitter widget in TypeScript. Currently, I am encountering several errors such as: ESLint: Unsafe call of an any typed value.(@typescript-eslint/no-unsafe-call) ESLint: Unsafe member access .catch on an any value.(@ ...

Encountering an obscure issue when using Discord.js v14 after attempting to cancel and resubmit a modal

I'm currently working on a Discord bot using modals in Discord.js v14. These modals appear after the user clicks a button, and an .awaitModalSubmit() collector is triggered to handle one modal submission interaction by applying certain logic. The .awa ...

The openapi-generator with the typescript-angular language option appears to be experiencing some issues

I am facing issues with generating angular code using the openapi-generator for language typescript-angular. Do you have any suggestions on how to resolve this? I have already tried running openapi-generator help meta and it seems that -l is a valid option ...

What is the proper way to include type annotation in a destructured object literal when using the rest operator?

When working with objects, I utilize the spread/rest operator to destructure an object literal. Is there a way to add type annotation specifically to the rest part? I attempted to accomplish this task, but encountered an error when running tsc. const { ...

How can a child component trigger an event in its parent component?

Currently, I have tabs implemented with a form and a button in tab1. In the parent component, there is an event that deactivates the current tab and activates the next one. Can anyone advise on how to call this event from the child component? gotosecond ...

Navigating through a multidimensional array in Angular 2 / TypeScript, moving both upwards and downwards

[ {id: 1, name: "test 1", children: [ {id: 2, name: "test 1-sub", children: []} ] }] Imagine a scenario where you have a JSON array structured like the example above, with each element potenti ...

What is a Mongoose Schema type in TypeScript and how can it be used as a custom

https://i.stack.imgur.com/mtlRi.png Could anyone assist me with storing a custom object that includes attributes from the StationRating interface? ...

Angular Universal causing issues with updating the DOM component

@Component({ selector: 'mh-feature-popup', template: ` <div class="full"> <div> <div class="container-fluid" [@featurepop]="state"> <div class="row"> <div class="col-xs-12 col-md-4 col-md-offse ...

Error: The URL constructor is unable to process /account as a valid URL address

Working on a new social media app using appwrite and nextjs, encountering an error "TypeError: URL constructor: /account is not a valid URL" upon loading the website. Here's the current file structure of my app: File Structure Below is the layout.tsx ...

I am looking to implement tab navigation for page switching in my project, which is built with react-redux and react-router

Explore the Material-UI Tabs component here Currently, I am implementing a React application with Redux. My goal is to utilize a panelTab from Material UI in order to navigate between different React pages. Whenever a tab is clicked, <TabPanel value ...

Using TypeScript to automatically determine the argument type of a function by analyzing the return type of a different function

I am working on an interface with the following structure: interface Res<R = any> { first?(): Promise<R>; second(arg: { response: R }): void; } However, I noticed that when creating a plain object based on this interface, the response ...

Unable to modify the active property of the specified object as it is read-only

Presented here is the interface: export interface ProductCommand extends ProductDetailsCommand { } This is the ProductDetailsCommand interface: export interface ProductDetailsCommand { id: string; active: boolean; archive: boolean; title: ...