TypeScript: Enumeração do TypeScript (enum)

Última atualização: 2026-08-26

As enums são um dos poucos recursos de tipos do TypeScript que apresentam comportamento em tempo de execução — elas são tanto um tipo quanto geram objetos reais em JavaScript.

1. Enumeração numérica

(1) Sintaxe básica

TYPESCRIPT
enum Direction {
  Up,       // 0(Auto-increment from 0)
  Down,     // 1
  Left,     // 2
  Right     // 3
}

let dir: Direction = Direction.Up;
console.log(dir);                // 0
console.log(Direction[0]);       // "Up"(Inverse Mapping)

(2) Valores iniciais personalizados

TYPESCRIPT
enum Status {
  Active = 1,    // 1
  Inactive,      // 2(Auto-increment)
  Pending        // 3
}

enum HttpStatus {
  OK = 200,
  Moved = 301,
  BadRequest = 400,
  NotFound = 404,
  ServerError = 500
}

let code: HttpStatus = HttpStatus.OK;
console.log(code);  // 200

(3) Mapeamento reverso de enumerações numéricas

Após a compilação, as enumerações numéricas geram objetos de mapeamento bidirecional — é possível recuperar um valor pelo nome ou um nome pelo valor:

TYPESCRIPT
enum Role {
  Admin = 0,
  Editor = 1,
  Viewer = 2
}

// Forward Mapping: name → value
console.log(Role.Admin);   // 0

// Inverse Mapping: value → name
console.log(Role[0]);      // "Admin"
console.log(Role[1]);      // "Editor"

JavaScript gerado após a compilação:

JAVASCRIPT
var Role;
(function (Role) {
  Role[Role["Admin"] = 0] = "Admin";
  Role[Role["Editor"] = 1] = "Editor";
  Role[Role["Viewer"] = 2] = "Viewer";
})(Role || (Role = {}));


2. Enumeração de strings

(1) Sintaxe básica

Cada elemento de uma enumeração de cadeias de caracteres deve ser atribuído explicitamente — não há incremento automático:

TYPESCRIPT
enum EventType {
  Click = "click",
  Change = "change",
  Submit = "submit",
  Focus = "focus"
}

let event: EventType = EventType.Click;
console.log(event);  // "click"

(2) A enumeração de cadeias de caracteres não possui mapeamento inverso

TYPESCRIPT
enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

console.log(Color.Red);       // "RED"  ✅ Forward Mapping
// console.log(Color["RED"]); // undefined ❌ String enumeration has no reverse mapping
💡 Motivo: Os valores das enumerações numéricas são números, que podem ser usados como chaves de objetos; os valores das enumerações de cadeias de caracteres são cadeias de caracteres, o que entra em conflito com as chaves de objetos, portanto, o mapeamento reverso não pode ser implementado.

▶ Exemplo: Definindo status de pedidos usando uma enumeração

TYPESCRIPT
enum OrderStatus {
  Pending = "PENDING",
  Processing = "PROCESSING",
  Shipped = "SHIPPED",
  Delivered = "DELIVERED",
  Cancelled = "CANCELLED"
}

function getStatusLabel(status: OrderStatus): string {
  switch (status) {
    case OrderStatus.Pending: return "Pending";
    case OrderStatus.Processing: return "Processing...";
    case OrderStatus.Shipped: return "Shipped";
    case OrderStatus.Delivered: return "Delivered";
    case OrderStatus.Cancelled: return "Canceled";
  }
}

let currentStatus: OrderStatus = OrderStatus.Processing;
console.log(`Current Status:${getStatusLabel(currentStatus)}`);
console.log(`Status Code:${currentStatus}`);
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Current Status:Processing...
Status Code:PROCESSING


3. Enumerações heterogêneas

As enumerações podem conter uma mistura de valores numéricos e de cadeias de caracteres — mas isso não é recomendado:

TYPESCRIPT
enum Mixed {
  No = 0,
  Yes = "YES"
}
⚠️ Não recomendado: Enumerações heterogêneas podem facilmente causar confusão, e a documentação oficial do TypeScript também recomenda evitar seu uso. No desenvolvimento prático, você deve usar exclusivamente enumerações numéricas ou exclusivamente enumerações de string.



4. Enumerações const

const enum Substituído por uma expressão inline durante a compilação — não gera um objeto JavaScript, oferecendo melhor desempenho, mas com funcionalidade limitada:

(1) Sintaxe básica

TYPESCRIPT
const enum Color {
  Red = "RED",
  Green = "GREEN",
  Blue = "BLUE"
}

let c = Color.Red;
// After compilation:let c = "RED"(Direct Inline Replacement,No enumeration objects)

(2) Limitações das enumerações const

TYPESCRIPT
const enum Direction {
  Up = "UP",
  Down = "DOWN"
}

// ❌ const Enumerations cannot use reverse mapping.
// console.log(Direction[0]);

// ❌ const Enumerations cannot be iterated over at runtime
// for (let d in Direction) { }

// ✅ Only simple value references are allowed.
let dir = Direction.Up;  // Compile to let dir = "UP"

(3) A opção preserveConstEnums

Se você quiser que as enumerações const não sejam inlinadas, mas mantenham os objetos de enumeração, habilite preserveConstEnums: true:

TYPESCRIPT
// tsconfig.json
// "preserveConstEnums": true

const enum Status {
  Active = 1
}

let s = Status.Active;
// After compilation:Enumeration objects are still generated(But quotes are also inlined.)


5. Tempo de execução e segurança de tipos nas enumerações

(1) Enumerações como tipos

TYPESCRIPT
enum Role {
  Admin,
  Editor,
  Viewer
}

function checkAccess(role: Role): boolean {
  return role === Role.Admin || role === Role.Editor;
}

checkAccess(Role.Admin);   // ✅
checkAccess(0);            // ✅ Numeric enumerations accept numeric values(but ⚠️ not recommended)
// checkAccess(99);        // ✅ Compilation successful!Any number can be converted to——This is a numeric enumeration vulnerability.
🔥 As armadilhas das enumerações numéricas: Variáveis de tipos de enumeração numérica podem aceitar qualquer número — let r: Role = 99 é um valor válido. Isso ocorre porque as enumerações numéricas foram projetadas tendo em mente os sinalizadores de bits. Se você precisar de restrições rigorosas de valores, use enumerações de string ou tipos de união literais.

(2) A enumeração de strings é mais segura

TYPESCRIPT
enum Role {
  Admin = "ADMIN",
  Editor = "EDITOR",
  Viewer = "VIEWER"
}

let r: Role = Role.Admin;   // ✅
// r = "ADMIN";             // ❌ String enumeration does not accept regular strings.
// r = "SUPERADMIN";        // ❌ Only enumeration members are accepted


6. Enumerações x Tipos de união literais

Propriedade Enumeração Tipo de união literal
Código em tempo de execução Sim (são criados objetos) Não (tipos puros)
Mapeamento reverso Enumeração digital: Sim Não
Percorrer todos os valores Sim Não
Restrições de valor Enumeração numérica (mais flexível) Rigorosa
Sugestões de código Autocompletar membros de enumeração Autocompletar valores de união
Tamanho do pacote Aumenta o tamanho do código Tamanho zero
Interoperabilidade com JS Os valores de enumeração são objetos personalizados Strings/números nativos

(1) Cenários para o uso de enumerações

(2) Cenários que utilizam tipos de união literais (recomendados como primeira opção)

▶ Exemplo: Comparação dos dois métodos

TYPESCRIPT
// Method 1:Enumeration
enum Direction1 {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT"
}

// Method 2:Literal Union Types(Recommendations)
type Direction2 = "UP" | "DOWN" | "LEFT" | "RIGHT";

// The two are equivalent in terms of type constraints.
function move1(dir: Direction1): void { console.log(dir); }
function move2(dir: Direction2): void { console.log(dir); }

move1(Direction1.Up);  // ✅ "UP"
move2("UP");           // ✅ Use the string directly,Even simpler

// But enumerations can be iterated over
console.log(Object.values(Direction1));
// ["UP", "DOWN", "LEFT", "RIGHT"]

// Literal union types cannot be iterated over(Pure compile-time types)
▶ Experimente

Saída:

TEXT 📖 Somente leitura
// Executed successfully


▶ Exemplo: Enums const para segurança de tipos com custo zero

TYPESCRIPT
const enum LogLevel {
  Debug = 0,
  Info = 1,
  Warn = 2,
  Error = 3
}

function log(level: LogLevel, message: string): void {
  const prefix = ["DEBUG", "INFO", "WARN", "ERROR"][level];
  console.log(`[${prefix}] ${message}`);
}

log(LogLevel.Info, "Server started");   // Compiles to: log(1, "Server started")
log(LogLevel.Error, "Connection lost"); // Compiles to: log(3, "Connection lost")
▶ Experimente

Saída:

TEXT 📖 Somente leitura
[INFO] Server started
[ERROR] Connection lost
💡 Key Point: const enum members are inlined at compile time—no enum object is emitted in the JS output, resulting in smaller bundle size.


❓ Perguntas Frequentes

P: Deve-se usar enumerações? R: A comunidade do TypeScript está dividida em dois campos — um acredita que as enumerações são uma característica distintiva do TypeScript e devem ser usadas, enquanto o outro acredita que os tipos de união literais são mais leves e mais recomendados. Conselho prático: se você precisar apenas de restrições de tipo (o que ocorre na maioria das situações), use tipos de união literais; se precisar de comportamento em tempo de execução (como iteração ou mapeamento reverso), use enumerações.

P: Por que as enumerações numéricas aceitam qualquer número? R: Essa é uma decisão de projeto do TypeScript — as enumerações numéricas suportam sinalizadores de bits (enum Perm { Read = 1, Write = 2, Execute = 4 }), e as combinações de bits Read | Write = 3 são válidas, mas não estão incluídas na definição da enumeração. Portanto, o tipo de enumeração numérica flexibilizou suas restrições. Se você não quiser esse comportamento, use enumerações de string ou tipos de união literais.

P: Qual é a diferença entre uma enumeração const e uma enumeração comum? R: Uma enumeração const é incorporada em tempo de compilação — Color.Red é substituída diretamente por "RED", e nenhum objeto de enumeração é gerado. A vantagem é um pacote menor e um desempenho mais rápido em tempo de execução; a desvantagem é que ela não pode ser mapeada de forma reversa, não pode ser iterada e não pode ser usada em contextos dinâmicos. Priorize o uso de enumerações const (a menos que você precise de recursos de tempo de execução).

P: As enumerações podem ser combinadas com interfaces ou aliases de tipo? R: Sim. Os valores das enumerações podem ser usados como tipos de propriedade para interfaces — interface Config { role: Role }. Os membros das enumerações também podem ser usados como membros de tipos de união — type Mixed = Role.Admin | "superadmin". As enumerações são um conceito unificado de tipo e valor, oferecendo flexibilidade de uso.

📖 Resumo

📝 Exercícios

  1. Problema básico (Dificuldade ⭐): Dada uma enumeração de caracteres Season (Primavera/Verão/Outono/Inverno), escreva uma função que retorne uma descrição do intervalo de meses correspondente com base na estação do ano.
  2. Exercício avançado (Dificuldade ⭐⭐): Use const enum para definir métodos HTTP (GET/POST/PUT/DELETE) e, em seguida, defina uma interface Request que inclua as propriedades method e url. Crie vários objetos de solicitação para verificar as restrições de tipo.
  3. Desafio (Dificuldade: ⭐⭐⭐): Use tipos de união literal em vez de enumerações para implementar um “sistema de permissões”: defina Permission = "read" | "write" | "execute" | "admin" e, em seguida, implemente a função hasPermission(userPerms: Permission[], required: Permission): boolean para verificar se um usuário possui uma permissão específica (o administrador tem todas as permissões).
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%