84

I have an enum like this:

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

Could you let me know how to get enum key by value please? i.e., I need to pass "BLUE COLOR" and get 'BLUE'.

Colors["BLUE COLOR"] gives error 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'.

wentjun
  • 40,384
  • 10
  • 95
  • 107
MAK
  • 1,915
  • 4
  • 20
  • 44

8 Answers8

68

If you want to get your enum key by value in that case you have to rewrite your enum in following manners: But same format also might be work in older version as well.

For Vanilla Js it should be like below:

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

For .tsx it should be like below:

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

For .ts it should be like below:

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

Then you can get like this way:

Retrieve enum key by value:

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

Output:

enter image description here

Another way: Retrieve enum key by value:

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

console.log(enumKey);

Output:

enter image description here

Test on jsfiddle:

Coding sample on jsfiddle

Note: There are new annoucement published on 25th August with TypeScript 4.8. Please be aware of it. You could have a look here.

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43
49
const findMe = Object.keys(Colors)[Object.values(Colors).indexOf("BLUE COLOR")];

https://jsfiddle.net/anniebbird/agy3unfk/3/

Anna
  • 2,911
  • 6
  • 29
  • 42
25

I am using this 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] : '';
}

Tests with jest

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

  enum TestEnumWithString {
    ZERO = 'ZERO'
  }

  it('should return correct key when enum has number values', function() {
    const key = getEnumKeyByEnumValue(TestEnumWithNumber, TestEnumWithNumber.ZERO);
    expect(key).toBe('ZERO');
  });

  it('should return correct key when enum has string values', function() {
    const key = getEnumKeyByEnumValue(TestEnumWithString, TestEnumWithString.ZERO);
    expect(key).toBe('ZERO');
  });

  it('should return correct key by passing corresponding string value', function() {
    const key = getEnumKeyByEnumValue(TestEnumWithString, 'ZERO');
    expect(key).toBe('ZERO');
  });
});

Hope it helps someone

Nux
  • 5,890
  • 13
  • 48
  • 74
15

Improved getEnumKeyByEnumValue without using any:

export function getEnumKeyByEnumValue<
  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] : '';
}
Nazarii Repak
  • 151
  • 1
  • 6
6

try like this

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

 console.log(Object.keys(Colors)[Object.values(Colors).indexOf('BLUE COLOR' as unknown as Colors)]);
nikiphoros
  • 93
  • 1
  • 5
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 11 '22 at 06:39
2

Improved getEnumKeyByEnumValue by adding type checks:

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);

// next line will trigger: 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/

josue.0
  • 775
  • 1
  • 10
  • 23
1

You can do something like this fetching the enum keys:

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

for (let item in Colors) { 
    if (Colors[item] === "BLUE COLOR") { 
        alert(item)
    }
}
Emanuele Scarabattoli
  • 4,103
  • 1
  • 12
  • 21
1

I'd like to fix the code a little:

return Object.keys(myEnum).find(x => myEnum[x] === enumValue);
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 01 '23 at 12:17
  • It doesn't work for my enum with string values: `TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof MyEnum'.   No index signature with a parameter of type 'string' was found on type 'typeof MyEnum'. ` – PatrykMilewski May 18 '23 at 15:19