Estaba buscando una respuesta que pueda obtener un enum
de a string
, pero en mi caso, los valores de las enumeraciones tenían valores de cadena diferentes. El OP tenía una enumeración simple Color
, pero tenía algo diferente:
enum Gender {
Male = 'Male',
Female = 'Female',
Other = 'Other',
CantTell = "Can't tell"
}
Cuando intenta resolver Gender.CantTell
con una "Can't tell"
cadena, vuelve undefined
con la respuesta original.
Otra respuesta
Básicamente, se me ocurrió otra respuesta, fuertemente inspirada por esta respuesta :
export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
(enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];
Notas
- Tomamos el primer resultado de
filter
, asumiendo que el cliente está pasando una cadena válida de la enumeración. Si no es el caso, undefined
será devuelto.
- Echamos
enumObj
a any
, ya que con mecanografiado 3.0+ (en la actualidad el uso de mecanografiado 3.5), el enumObj
se resuelve como unknown
.
Ejemplo de uso
const cantTellStr = "Can't tell";
const cantTellEnumValue = stringToEnumValue<typeof Gender, Gender>(Gender, cantTellStr);
console.log(cantTellEnumValue); // Can't tell
Nota: Y, como alguien señaló en un comentario, también quería usar el noImplicitAny
.
Versión actualizada
Sin yeso any
y tipificaciones adecuadas.
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];
Además, la versión actualizada tiene una forma más fácil de llamarlo y es más legible:
stringToEnumValue(Gender, "Can't tell");
--noImplicitAny
(en VS desmarcado "Permitir tipos 'cualquiera' implícitos"). Produceerror TS7017: Index signature of object type implicitly has an 'any' type.
Para mí esto funcionó:var color: Color = (<any>Color)[green];
(probado con la versión 1.4)