Hvordan lete etter en nøkkel med verdi i Typescript Enum?


Jeg vil søke etter en Enum med verdi, og få nøkkelen til den. Dette er hva jeg har nå:

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

Kan vi ikke gjøre det enklere? Det virker som overkomplisering..

Egentlig vil jeg bare ha value.name() i Java.

REDIGER: MyEnum er noe sånt som dette:

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

Svar #1

Hvis du ser på MyEnum ved kjøring, vil det i hovedsak være et objekt som dette:

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

Det finnes ingen automatisk omvendt oppslag for objekter i JavaScript, så du må skrive noe som din find()-funksjon for å gjøre det. Så jeg tror ikke det finnes noe enklere, nei.

Hadde enumen din vært numerisk, ville TypeScript gitt deg disse omvendte tilordningene automatisk:

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

Men akk, du bruker en strengenum, så det finnes ingen magisk løsning her.

Hvis du ofte trenger å gjøre et reversoppslag og ikke vil fortsette å iterere over tabeller for å gjøre det, kan du bygge et reverskartleggingsobjekt på forhånd med en hjelpefunksjon som dette:

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

Og bruk det sånn:

// 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"

Selvfølgelig er reverseMapping()-funksjonen muligens mer «over-engineered» enn find(), så det er opp til deg om det er verdt det for deg. Jeg vil trolig fortsette å bruke find() (selv om den er mer sterkt typet, ikke at du har spurt om det) med mindre jeg støter på et slags problem med den (f.eks. ytelse ved å konstant iterere gjennom en virkelig enorm enum... usannsynlig).

Uansett, håper det hjelper. Lykke til!

Relaterte artikler