Como obter nomes de enum em TypeScript: a mágica por baixo dos panos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: A pergunta eterna no Stack Overflow



Você já se perguntou como desenvolvedores experientes em TypeScript obtêm os nomes dos valores de enum? Se você já deu uma olhada no Stack Overflow, certamente viu a pergunta com milhares de visualizações: "How to get names of enum entries?". Parece simples, não? Mas na prática, muitos iniciantes (e não só) tropeçam nesse ponto.



Neste artigo, não vamos apenas dar a resposta pronta. Vamos mergulhar por baixo dos panos do TypeScript e entender como os enum funcionam exatamente, como o compilador os transforma em JavaScript e por que algumas abordagens para obter nomes podem levar a bugs inesperados. Prontos? Vamos lá!



O que é um enum em TypeScript e para que servem seus nomes?



Enum (enumeração) é uma maneira conveniente de definir um conjunto de constantes nomeadas. Em TypeScript, eles podem ser numéricos (padrão) ou de string. Mas o que fazer se você precisar obter o nome de um valor específico? Por exemplo, você recebeu da API um código de status 403 e quer exibir para o usuário uma mensagem compreensível como "Forbidden".



enum HttpStatus {  OK = 200,  NotFound = 404,  Forbidden = 403}

// Nossa tarefa: obter o nome "Forbidden" a partir do valor 403


Parece que o TypeScript deveria fornecer um método embutido para isso. Mas não. É preciso escrever sua própria lógica. E é aí que a coisa fica interessante.



Solução "na marra": Object.keys e Object.values



A maneira mais óbvia é usar os métodos Object.keys() ou Object.values(). Muitos iniciantes escrevem algo assim:



function getEnumName(enumObj: any, value: number): string | undefined {  const keys = Object.keys(enumObj);  return keys.find(key => enumObj[key] === value);}

console.log(getEnumName(HttpStatus, 403)); // "Forbidden" — funciona!


Parece lógico, certo? Sim. Mas se você tentar esse código em um enum numérico, uma surpresa o espera. Vamos ver no que nosso HttpStatus é compilado.



Por baixo dos panos: compilação de enum numérico



Quando o TypeScript compila um enum numérico, ele cria um objeto com mapeamento reverso (reverse mapping). Aqui está como fica o JavaScript compilado:



var HttpStatus;(function (HttpStatus) {    HttpStatus[HttpStatus["OK"] = 200] = "OK";    HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";    HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";})(HttpStatus || (HttpStatus = {}));

// No final, o objeto HttpStatus fica assim:// { // "200": "OK", // "404": "NotFound", // "403": "Forbidden", // "OK": 200, // "NotFound": 404, // "Forbidden": 403 // }


Viu o truque? O compilador adiciona tanto chaves numéricas quanto chaves de string. Portanto, Object.keys(HttpStatus) retornará não apenas ["OK", "NotFound", "Forbidden"], mas também ["200", "404", "403"]. Isso quebra a lógica da nossa solução simples!



Para contornar isso, é preciso filtrar as chaves numéricas:



function getEnumNameSafe(enumObj: any, value: number): string | undefined {  const keys = Object.keys(enumObj).filter(key => isNaN(Number(key)));  return keys.find(key => enumObj[key] === value);}


Mas esse código parece uma gambiarra. Existe uma maneira melhor?



Enums de string: uma história diferente



Se você usa enums de string, o mapeamento reverso não é criado. Isso simplifica a tarefa:



enum Direction {  Up = "UP",  Down = "DOWN",  Left = "LEFT",  Right = "RIGHT"}

// Object.keys(Direction) retornará apenas ["Up", "Down", "Left", "Right"] — perfeito!


Mas e se você precisar obter o nome a partir do valor? O mesmo Object.keys funciona perfeitamente:



function getStringEn                

Blogs

Book Recommendations