Eu estava procurando por uma resposta que pudesse obter um enum
de a string
, mas no meu caso, os valores de enumerações tinham valores de sequência diferentes. O OP tinha um enum simples para Color
, mas eu tinha algo diferente:
enum Gender {
Male = 'Male',
Female = 'Female',
Other = 'Other',
CantTell = "Can't tell"
}
Quando você tenta resolver Gender.CantTell
com uma "Can't tell"
sequência, ela retorna undefined
com a resposta original.
Outra resposta
Basicamente, eu vim com outra resposta, fortemente inspirada por esta resposta :
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 o primeiro resultado de
filter
, supondo que o cliente esteja passando uma string válida do enum. Se não for o caso, undefined
será devolvido.
- Nós fundido
enumObj
para any
, porque com texto dactilografado 3.0+ (actualmente a utilizar texto dactilografado 3,5), a enumObj
é resolvido como unknown
.
Exemplo de Uso
const cantTellStr = "Can't tell";
const cantTellEnumValue = stringToEnumValue<typeof Gender, Gender>(Gender, cantTellStr);
console.log(cantTellEnumValue); // Can't tell
Nota: E, como alguém apontou em um comentário, eu também queria usar o noImplicitAny
.
Versão atualizada
Sem elenco any
e tipografia adequada.
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];
Além disso, a versão atualizada possui uma maneira mais fácil de chamá-la e é mais legível:
stringToEnumValue(Gender, "Can't tell");
--noImplicitAny
(no VS desmarcado "Permitir tipos implícitos 'qualquer'"). Produzerror TS7017: Index signature of object type implicitly has an 'any' type.
para mim isso funcionou:var color: Color = (<any>Color)[green];
(testado com a versão 1.4)