0Pricing
TypeScript Academy · Aula

Restrição pelo Discriminante

Permita que o TypeScript restrinja variantes em instruções switch.

Restrição pelo Discriminante é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de TypeScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de TypeScript Academy inclui 4 aulas no total.

Refinamento pelo discriminante

Depois de verificar o discriminante, TypeScript refina a união para o membro correspondente e disponibiliza seus campos específicos. Esse é o benefício principal do padrão.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function area(s: Shape) {
  if (s.kind === "circle") return Math.PI * s.radius ** 2;
  return s.side ** 2;
}
console.log(area({ kind: "circle", radius: 2 }).toFixed(2));

Seleção pelo discriminante

Uma seleção switch sobre o discriminante é a maneira mais clara de tratar cada variante. Dentro de cada case, o tipo é refinado automaticamente.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function area(s: Shape): number {
  switch (s.kind) {
    case "circle": return Math.PI * s.radius ** 2;
    case "square": return s.side ** 2;
  }
}
console.log(area({ kind: "square", side: 5 }));

Campos específicos de cada membro em cada caso

No caso "circle", s.radius está disponível, mas s.side não está. TypeScript sabe exatamente em qual membro você está.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function describe(s: Shape) {
  switch (s.kind) {
    case "circle": return "r=" + s.radius;
    case "square": return "side=" + s.side;
  }
}
console.log(describe({ kind: "circle", radius: 9 }));

Refinamento baseado em condições

Você não precisa usar uma seleção. Uma simples condição if que compare o discriminante produz um refinamento igualmente eficaz.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function perimeter(s: Shape): number {
  if (s.kind === "circle") {
    return 2 * Math.PI * s.radius;
  }
  return 4 * s.side;
}
console.log(perimeter({ kind: "square", side: 3 }));

O acesso ao campo errado falha

Antes do refinamento, você não pode acessar um campo específico de um membro. TypeScript informa um erro porque a propriedade não existe em todos os membros.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function broken(s: Shape) {
  // Error: radius does not exist on Square
  // return s.radius;
  return s.kind;
}
console.log(broken({ kind: "square", side: 1 }));

Refinamento com discriminantes booleanos

Para uma união { ok: true } | { ok: false }, verificar if (r.ok) refina o tipo para o membro de sucesso.

type Result =
  | { ok: true; data: string }
  | { ok: false; error: string };

function handle(r: Result): string {
  if (r.ok) return "Data: " + r.data;
  return "Error: " + r.error;
}
console.log(handle({ ok: false, error: "boom" }));

Refinamento por retorno antecipado

Retornar antecipadamente para uma variante refina o restante do código para as outras variantes, uma maneira organizada de tratar os casos um por vez.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function label(s: Shape): string {
  if (s.kind === "circle") return "circle";
  // s is now narrowed to Square here
  return "square with side " + s.side;
}
console.log(label({ kind: "square", side: 8 }));

Combinação com outras condições

Você pode combinar a verificação do discriminante com outras lógicas. TypeScript mantém o refinamento enquanto a condição do discriminante for verdadeira nesse ramo.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function bigCircle(s: Shape): boolean {
  return s.kind === "circle" && s.radius > 100;
}
console.log(bigCircle({ kind: "circle", radius: 150 }));

Refinamento em filtros de matrizes

O refinamento também funciona dentro de funções de retorno. Aqui cada forma é verificada individualmente à medida que iteramos.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const shapes: Shape[] = [
  { kind: "circle", radius: 1 },
  { kind: "square", side: 2 }
];
shapes.forEach(s => {
  if (s.kind === "circle") console.log("c", s.radius);
  else console.log("s", s.side);
});

Retornos de seleções permanecem seguros quanto aos tipos

Quando uma seleção trata todos os casos e retorna um valor, TypeScript infere um tipo de retorno preciso a partir da união de todos os resultados dos casos.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function tag(s: Shape) {
  switch (s.kind) {
    case "circle": return s.radius;
    case "square": return s.side;
  }
}
console.log(tag({ kind: "circle", radius: 4 }));

Reunindo o refinamento

Seja usando switch ou if, é a verificação do discriminante que torna o acesso aos campos dos membros seguro. Em seguida, vamos garantir que todos os casos sejam tratados.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

function area(s: Shape): number {
  return s.kind === "circle" ? Math.PI * s.radius ** 2 : s.side ** 2;
}
console.log(Math.round(area({ kind: "circle", radius: 10 })));

Verificação rápida: refinamento

Teste sua compreensão do refinamento por discriminantes.

Recapitulação: refinamento pelo discriminante

Você viu que verificar o discriminante com switch ou if refina a união para um único membro, expondo apenas os campos específicos desse membro. Retornos antecipados e condições combinadas também preservam o refinamento.

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number };

const s: Shape = { kind: "square", side: 7 };
console.log(s.kind === "square" ? s.side : 0);

Perguntas Frequentes

A aula “Restrição pelo Discriminante” é grátis?

Sim — o texto completo de “Restrição pelo Discriminante” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de TypeScript Academy, atualize para CoddyKit PRO. O curso de TypeScript Academy inclui 4 aulas no total.

O que vou aprender em “Restrição pelo Discriminante”?

Permita que o TypeScript restrinja variantes em instruções switch. Você pratica TypeScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar TypeScript Academy?

Nenhuma experiência prévia é necessária. TypeScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Restrição pelo Discriminante”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de TypeScript Academy?

Sim. Cada aula de TypeScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Construindo Uniões Discriminadas
  2. Restrição pelo Discriminante
  3. Verificação de Exaustividade com never
  4. Modelando Máquinas de Estado
← Voltar para TypeScript Academy