Médio TypeScript

Usando união de literais e as const

Enunciado

Crie um tipo Status como união de literais: 'active' | 'inactive' | 'pending'. Depois, crie um objeto const StatusValues com as propriedades Active, Inactive e Pending usando as const, de forma que os valores sejam exatamente essas strings. Escreva uma função getStatusMessage(status: Status): string que retorna uma mensagem descritiva para cada status. Teste com StatusValues.Active e StatusValues.Pending.

Requisitos

  • Definir type Status como união de literais.
  • Criar StatusValues com as const contendo as três propriedades.
  • Implementar getStatusMessage que retorna mensagens específicas para cada status.
  • Chamar a função com StatusValues.Active e StatusValues.Pending e imprimir.

Código inicial

// Defina o tipo Status

// Crie o objeto StatusValues com as const

// Implemente getStatusMessage

// Teste com StatusValues.Active e StatusValues.Pending

Saída esperada

Status active: Usuário ativo
Status pending: Aguardando aprovação
Ver dica

Use typeof StatusValues[keyof typeof StatusValues] para extrair o tipo dos valores do objeto, ou simplesmente defina a união manualmente. A função pode usar um switch ou um mapa de mensagens.

Mostrar solução
// Tipo união de literais
type Status = 'active' | 'inactive' | 'pending';

// Objeto com as const para valores imutáveis
const StatusValues = {
  Active: 'active',
  Inactive: 'inactive',
  Pending: 'pending'
} as const;

// Função que retorna mensagem baseada no status
function getStatusMessage(status: Status): string {
  switch (status) {
    case StatusValues.Active:
      return 'Usuário ativo';
    case StatusValues.Inactive:
      return 'Usuário inativo';
    case StatusValues.Pending:
      return 'Aguardando aprovação';
    default:
      // Nunca deve chegar aqui, mas o TypeScript exige exaustividade
      const _exhaustive: never = status;
      return _exhaustive;
  }
}

// Testes
console.log(`Status ${StatusValues.Active}: ${getStatusMessage(StatusValues.Active)}`);
console.log(`Status ${StatusValues.Pending}: ${getStatusMessage(StatusValues.Pending)}`);

Passo a passo

  1. Definimos o tipo Status como união de três strings literais.
  2. Criamos StatusValues com as const, o que faz com que cada propriedade tenha tipo literal (ex.: 'active').
  3. A função getStatusMessage recebe um parâmetro do tipo Status.
  4. Usamos switch para comparar com os valores de StatusValues. Como são literais, o TypeScript verifica se todos os casos são cobertos.
  5. No default, usamos never para garantir que todos os casos foram tratados (exaustividade).
  6. Chamamos a função com StatusValues.Active e StatusValues.Pending e imprimimos.

Por que funciona

as const torna o objeto imutável e preserva os tipos literais de suas propriedades. Assim, StatusValues.Active tem tipo 'active', que é compatível com a união Status. A verificação de exaustividade com never ajuda a evitar esquecimento de casos.

Erros comuns

  • Esquecer as const: sem ele, StatusValues.Active seria inferido como string, causando erro ao passar para getStatusMessage.
  • Não tratar todos os casos: se faltar um case, o TypeScript não reclama automaticamente a menos que você use never no default.
  • Usar StatusValues.Active como tipo: StatusValues.Active é um valor, não um tipo. Para o tipo, use typeof StatusValues.Active.

Outra forma de resolver

Usar um enum:

enum Status {
  Active = 'active',
  Inactive = 'inactive',
  Pending = 'pending'
}

Mas isso gera código extra. A união de literais é mais leve.

Saída esperada

Status active: Usuário ativo
Status pending: Aguardando aprovação