Stavo cercando una risposta che potesse ottenere un enum
da a string
, ma nel mio caso i valori di enum avevano una controparte di valori di stringa diversi. L'OP aveva un enum semplice per Color
, ma avevo qualcosa di diverso:
enum Gender {
Male = 'Male',
Female = 'Female',
Other = 'Other',
CantTell = "Can't tell"
}
Quando si tenta di risolvere Gender.CantTell
con una "Can't tell"
stringa, viene restituito undefined
con la risposta originale.
Un'altra risposta
Fondamentalmente, ho trovato un'altra risposta, fortemente ispirata da questa risposta :
export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
(enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];
Appunti
- Prendiamo il primo risultato di
filter
, supponendo che il client stia passando una stringa valida dall'enum. In caso contrario, undefined
verrà restituito.
- Abbiamo gettato
enumObj
a any
, perché con dattiloscritto 3.0+ (attualmente in uso tipografico 3.5), la enumObj
si risolve come unknown
.
Esempio di utilizzo
const cantTellStr = "Can't tell";
const cantTellEnumValue = stringToEnumValue<typeof Gender, Gender>(Gender, cantTellStr);
console.log(cantTellEnumValue); // Can't tell
Nota: E, come qualcuno ha sottolineato in un commento, volevo anche usare il noImplicitAny
.
Versione aggiornata
Nessun cast any
e digitazione corretta.
export const stringToEnumValue = <T, K extends keyof T>(enumObj: T, value: string): T[keyof T] | undefined =>
enumObj[Object.keys(enumObj).filter((k) => enumObj[k as K].toString() === value)[0] as keyof typeof enumObj];
Inoltre, la versione aggiornata ha un modo più semplice per chiamarla ed è più leggibile:
stringToEnumValue(Gender, "Can't tell");
--noImplicitAny
(in VS deselezionato "Consenti 'qualsiasi' tipo implicito"). Produceerror TS7017: Index signature of object type implicitly has an 'any' type.
per me questo ha funzionato:var color: Color = (<any>Color)[green];
(testato con la versione 1.4)