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!
