3

I would like to search an Enum with value, and get the key of it. This is what i have now:

  private find(value: MyEnum): string {
    for (const key in MyEnum) {
      if (value === MyEnum[key]) {
        return key;
      }
    }
    return null;
  }

Can we not make it simpler? It seems to be an overengineering..

Actually all i want is value.name() in Java.

EDIT: MyEnum is sth like this:

export enum MyEnum {
  YES = 'x',
  NO = 'y'
}

1 Answer 1

6

If you look at MyEnum at runtime, it will essentially be an object like this:

{ YES: 'x', NO: 'y' }

There is no automatic reverse lookup for objects in JavaScript, so you need to write something like your find() function to do it. So I don't think there's anything simpler, no.

Had your enum been numeric, TypeScript would give you those reverse mappings automatically:

enum MyEnum {
    YES = 1,
    NO = 0
}
const oneKey = MyEnum[1]; // "YES" (typed as string)
const zeroKey = MyEnum[0]; // "NO" (typed as string)

But alas, you are using a string enum, so there's no magical answer here.


If you often need to do a reverse lookup and don't want to keep iterating over arrays to do it, you can build a reverse-mapping object in advance with a helper function like this:

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

function reverseMapping<T extends Record<keyof T, keyof any>>(t: T): ReverseMapping<T> {
    const ret = {} as ReverseMapping<T>;
    (Object.keys(t) as Array<keyof T>).forEach(k => ret[t[k]] = k as any);
    return ret;
}

And then use it like this:

// do this once
const reverseMyEnum = reverseMapping(MyEnum); // reverseMyEnum: { x: "YES", y: "NO" }

// reuse reverseMyEnum for reverse lookups:
const xKey = reverseMyEnum.x; // xKey: "YES"
const yKey = reverseMyEnum.y; // yKey: "NO"
const randKey = reverseMyEnum[Math.random() < 0.5 ? "x" : "y"]; // randKey: "YES" | "NO"

Of course, the reverseMapping() function is possibly more "over-engineered" than find(), so it's up to you whether it's worth it to you. I would tend to keep using find() (although more strongly typed, not that you've asked for that) unless I was running into some kind of problem with it (e.g., performance from constantly iterating through a truly enormous enum... unlikely).

Anyway hope that helps. Good luck!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.