Enums TypeScript: Guia Completo com Exemplos e Melhores Práticas

A expressão “Enums TypeScript” surge com frequência no universo do desenvolvimento com a linguagem TypeScript.

TypeScript, apesar de ser uma das linguagens mais recentes, conquistou um lugar de destaque entre os programadores. Ela funciona como uma extensão (um superconjunto) do JavaScript. Isso significa que qualquer código JavaScript válido também será válido em TypeScript. No entanto, TypeScript adiciona tipagem estática, um recurso que não existe no JavaScript.

Mas, afinal, o que são Enums em TypeScript? Quais os seus usos e como podemos criá-los? Este artigo abordará todos os pontos essenciais sobre Enums.

O que são Enums em TypeScript?

Enums (tipos enumerados) são estruturas de dados com um tamanho fixo, que armazenam um conjunto de valores imutáveis (constantes). TypeScript não é a única linguagem que utiliza Enums; elas também estão presentes em linguagens orientadas a objetos, como C# e Java.

Em TypeScript, enums permitem aos desenvolvedores criar um conjunto de opções distintas ou documentar intenções de forma clara. São importantes para definir valores ou propriedades que só podem assumir um número específico de estados. Um exemplo clássico é o número de continentes do mundo, que é fixo em sete.

Resumidamente, as enums em TypeScript oferecem:

  • Flexibilidade para documentar e expressar intenções e cenários de uso de maneira simples.
  • A capacidade de criar constantes personalizadas em JavaScript de forma eficiente.
  • Economia de tempo de compilação e de execução ao traduzir código TypeScript para JavaScript.

Enums em TypeScript podem ser do tipo string ou numérico. É importante notar que essas enumerações são pré-processadas e não passam por testes durante a fase de execução. O TypeScript converte/traduz enums para código JavaScript.

Tipos Diferentes de Enums em TypeScript

Agora que você já entende o conceito de Enums, é hora de vê-los em ação no TypeScript. Você pode configurar um ambiente de desenvolvimento local baixando TypeScript e Node.js, ou optar por usar plataformas online. Neste artigo, vamos usar o Playground do TypeScript para demonstrar os diferentes tipos de enums.

Aqui estão os diferentes tipos de Enum no TypeScript:

#1. Enums Numéricos

Para criar um enum, você precisa utilizar a palavra-chave ‘enum’ seguida pelo nome que deseja dar ao enum. Depois, define os membros do enum entre chaves. Veja um exemplo de enum numérico:

enum CardinalDirections {
    North = 5,
    East,
    South,
    West,
};

Este código define um enum chamado `CardinalDirections` que tem quatro membros. Neste caso, existem apenas quatro valores possíveis (Norte, Leste, Sul e Oeste), o que torna os enums uma excelente opção para armazenar dados com opções limitadas.

Atribuímos o valor 5 a `CardinalDirections.North`. Os valores dos outros membros não foram definidos, mas o TypeScript fará isso automaticamente. O valor de `CardinalDirections.East` será 6, pois o TypeScript incrementa o valor do membro anterior em 1.

Portanto, o valor de `CardinalDirections.West` será 8.

E se não definirmos um valor para o primeiro membro entre chaves? Nosso enum ficaria assim:

enum CardinalDirections {
    North,
    East,
    South,
    West,
};

Neste caso, o TypeScript atribui o valor 0 para o membro `North`. Se você consultar o valor de `CardinalDirections.West`, receberá 3.

#2. Enums de String

Em um enum de string, cada membro deve ser inicializado com outro membro string ou com uma string literal. Veja um exemplo de enum de string:

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

Diferente dos enums numéricos, os valores dos membros não são incrementados automaticamente. Ao executar este código:

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}
console.log(Direction.Right)

Você obterá como resultado:

“RIGHT”

#3. Enums Heterogêneos

Você pode misturar membros numéricos e de string para criar um enum heterogêneo. Veja um exemplo:

enum HeterogeneousEnum {
    No = 0,
    Yes = "YES",
}

#4. Membros de Enum Constantes e Computados

Os membros de um enum têm valores associados que podem ser ‘constantes’ ou ‘computados’.

Este é um exemplo de enum constante:

enum E1 {
    X,
    Y,
    Z,
}

Nesse caso, o primeiro membro do enum não tem um inicializador e o TypeScript atribui o valor 0 a ele.

Considere também este exemplo:

enum E1 {
    X=1,
    Y,
    Z,
}

Este também é um enum constante, pois o primeiro membro recebe um valor e a regra de incremento é aplicada aos demais.

Enums computados misturam membros constantes e computados. Veja este exemplo:

enum Color {
    Red = 100,
    Green = (Math.random() * 100),
    Blue = 200
}

O membro `Blue` é um membro constante, enquanto o membro `Green` é um enum computado, cujo valor depende da função `Math.random()` em tempo de execução.

#5. Enums Constantes

Enums constantes são utilizados para otimizar o desempenho de enums numéricos. Para isso, declaramos o enum como `const`.

Veja este código que representa os dias da semana:

enum Weekday {
    Monday = 1,
    Tuesday,
    Wednesday,
    Thursday,
    Friday
}

Ao executar `console.log(Weekday.Thursday)`, receberemos o valor 4. Ao verificar o código JavaScript gerado em tempo de compilação, encontraremos o seguinte:

"use strict";
var Weekday;
(function (Weekday) {
    Weekday[Weekday["Monday"] = 1] = "Monday";
    Weekday[Weekday["Tuesday"] = 2] = "Tuesday";
    Weekday[Weekday["Wednesday"] = 3] = "Wednesday";
    Weekday[Weekday["Thursday"] = 4] = "Thursday";
    Weekday[Weekday["Friday"] = 5] = "Friday";
})(Weekday || (Weekday = {}));
console.log(Weekday.Thursday);

Podemos otimizar este código declarando `Weekday` como constante:

const enum Weekday {
    Monday = 1,
    Tuesday,
    Wednesday,
    Thursday,
    Friday
}

Ao executar `console.log(Weekday.Thursday)`, o código JavaScript gerado em tempo de compilação será:

"use strict";
console.log(4 /* Weekday.Thursday */);

Perceba que o código JavaScript em tempo de compilação é otimizado quando você declara seu enum como `const`.

#6. Enums Ambientais

Enums ambientais utilizam a palavra-chave `declare` para descrever a estrutura de tipos enum já existentes. Veja este exemplo:

declare enum Color {
    Red,
    Green,
    Blue
}

Enums ambientais são declarados fora de qualquer módulo e podem ser usados para criar tipos reutilizáveis. É possível importar enumerações ambientais e utilizá-las em seus componentes, desde que elas sejam declaradas globalmente.

Agora você já conhece os diferentes tipos de enum em TypeScript. Vamos demonstrar como você pode utilizar enums de diversas maneiras, utilizando o seguinte código de referência:

enum Direction {
    North="N",
    East="E",
    South="S",
    West="W",
};

Aqui estão alguns exemplos de uso:

  • Extrair membros enum. Por exemplo, para acessar o Norte, podemos usar:

console.log(Direction.North); // Resultado: ‘N’

  • Utilizar membros enum: podemos escolher um membro específico para representar uma direção. Por exemplo:
const currentDirection = Direction.East;
console.log(`A direção atual é ${currentDirection}`);

Isso irá imprimir “A direção atual é E”.

Enums vs. Mapas de Objetos em TypeScript

Enums são utilizados para representar um conjunto finito de valores, como as cores do arco-íris ou os dias da semana. Enums são fortemente tipados, o que significa que erros são identificados durante o desenvolvimento. Veja um exemplo de enum TypeScript:

enum Color {
    Red,
    Green,
    Blue,
}

Mapas de objetos/dicionários/pares chave-valor armazenam e recuperam valores associados a chaves específicas. Em TypeScript, você pode usar mapas de objetos para armazenar qualquer tipo de dado. No entanto, eles não são estritamente tipados, o que significa que erros de tipo podem não ser identificados durante o desenvolvimento. Veja um exemplo de mapa de objetos representando as mesmas cores:

const colors = {
    red: "FF0000",
    green: "00FF00",
    blue: "0000FF",
};

As principais diferenças entre enums e mapas de objetos em TypeScript são:

  • Enums são estritamente tipados, enquanto mapas de objetos não.
  • Enums são um ‘Tipo’, enquanto mapas de objetos são uma estrutura de dados.
  • Enums não são flexíveis, enquanto mapas de objetos são flexíveis.

Melhores Práticas ao Utilizar Enums em TypeScript

Já mencionamos que TypeScript não é a única linguagem com o recurso enums. Seguir as melhores práticas garante que você escreva código limpo, otimizado e sem erros. Aqui estão algumas das melhores práticas ao escrever/utilizar enums em TypeScript:

  • Nomeie enums com a primeira letra maiúscula: Ao nomear uma enumeração, sempre capitalize a primeira palavra. Por exemplo, prefira um enum `Number` em vez de `number`.
  • Utilize enums para constantes: Enums são ideais para declarar um conjunto fixo de itens relacionados. Por exemplo, o número de dias em uma semana é fixo. Os membros de um enum nunca devem mudar durante a execução.
  • Evite o uso excessivo de enums: Pode acontecer de você aprender um novo conceito e querer utilizá-lo em todos os lugares no seu projeto TypeScript. No entanto, use enums com moderação. Eles são uma boa escolha quando você deseja manter a clareza do código.
  • Utilize enums para representar enums: Você pode utilizar enums para diferentes propósitos, mas o ideal é utilizá-los para representar enumerações, e não outras estruturas de dados.
  • Evite enumerações automáticas: O TypeScript atribui valores aos membros da enumeração se você não os definir explicitamente. Defina os valores das suas enumerações para evitar comportamentos inesperados na execução do seu código.
  • Documente seus enums: Sempre documente ou comente seu código, principalmente se ele for destinado a outras pessoas. Explique o propósito de cada enum e por que ele é a melhor opção em cada caso.

Você também pode explorar as principais bibliotecas TypeScript e tempos de execução para aprofundar seus conhecimentos como desenvolvedor.

Conclusão

Você aprendeu como definir enums em TypeScript, os diferentes tipos e seus casos de uso. O TypeScript é muito útil quando você busca clareza no seu código. No entanto, existem casos em que você deve evitá-los e optar por objetos.

Por exemplo, não utilize enums ao lidar com valores dinâmicos. Também não é possível utilizar enums como variáveis; seu programa retornará erros.

Você pode aprender mais sobre as diferenças entre TypeScript e JavaScript, caso ainda tenha dúvidas sobre os dois.