简体   繁体   中英

How to look for a key with value in Typescript Enum?

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'
}

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 (eg, performance from constantly iterating through a truly enormous enum... unlikely).

Anyway hope that helps. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM