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

后端 未结 1 1567
迷失自我
迷失自我 2021-01-14 17:03

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 MyEn         


        
相关标签:
1条回答
  • 2021-01-14 17:53

    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!

    0 讨论(0)
提交回复
热议问题