Verificação de Exaustividade com never
Detecte casos não tratados em tempo de compilação com never.
Verificação de Exaustividade com never é uma aula grátis de TypeScript Academy no CoddyKit. Esta é a aula 3 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.
O problema da exaustividade
Quando você adiciona um novo membro à união, é fácil esquecer de tratá-lo em algum lugar. A verificação de exaustividade transforma esse descuido em um erro de compilação.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
// If we add "triangle" later, we want every switch to complain.O tipo que nunca ocorre
O tipo never representa valores que nunca podem ocorrer. Se todos os casos forem tratados, o valor que chega ao ramo padrão terá o tipo never.
function fail(): never {
throw new Error("unreachable");
}
// never is assignable to nothing except never itself.Atribuição a never no caso padrão
No ramo default, atribua o valor a uma variável never. Se todas as variantes forem tratadas, a atribuição será compilada; caso contrário, ocorrerá um erro.
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;
default:
const _exhaustive: never = s;
return _exhaustive;
}
}
console.log(area({ kind: "square", side: 3 }));O que acontece quando você esquece um caso
Se você adicionar um membro triangle, mas esquecer seu caso, s no ramo padrão deixará de ser never, portanto a atribuição falhará durante a compilação.
// type Shape = ... | { kind: "triangle"; base: number; height: number };
// Now in default, s is { kind: "triangle"; ... }
// const _exhaustive: never = s; // Error: triangle not assignable to neverO auxiliar assertNever
Uma função assertNever reutilizável centraliza o padrão. Ela aceita never e lança uma exceção, documentando que o ramo não deveria ser alcançável.
function assertNever(value: never): never {
throw new Error("Unhandled case: " + JSON.stringify(value));
}
console.log(typeof assertNever);Uso de assertNever em uma seleção
Chame assertNever(s) no caso padrão. Isso impõe a exaustividade durante a compilação e produz um erro claro durante a execução se o ramo for alcançado.
function assertNever(value: never): never {
throw new Error("Unhandled: " + JSON.stringify(value));
}
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;
default: return assertNever(s);
}
}
console.log(area({ kind: "circle", radius: 1 }).toFixed(2));Segurança em compilação versus em execução
A verificação com never detecta casos ausentes antes de você executar o código, e o erro lançado protege você caso algo passe pela verificação de tipos e chegue à execução.
function assertNever(x: never): never {
throw new Error("Unhandled: " + String(x));
}
// Compile error if a case is missing; runtime throw as a backstop.
console.log("two layers of safety");Exaustividade sem um caso padrão
Se sua função tiver um tipo de retorno explícito e uma seleção abranger todos os casos, TypeScript também poderá sinalizar um retorno ausente, outra forma de verificar a exaustividade.
type Light = "red" | "yellow" | "green";
function next(l: Light): Light {
switch (l) {
case "red": return "green";
case "yellow": return "red";
case "green": return "yellow";
}
// No default needed; all cases return.
}
console.log(next("red"));Exaustividade com cadeias de condições
A mesma ideia funciona com if/else. Depois de tratar cada variante, o else final recebe um valor never.
function assertNever(x: never): never { throw new Error("bad"); }
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function name(s: Shape): string {
if (s.kind === "circle") return "circle";
else if (s.kind === "square") return "square";
else return assertNever(s);
}
console.log(name({ kind: "square", side: 2 }));Por que never é a ferramenta certa
Como never não pode ser atribuído a nenhum outro tipo, qualquer variante restante interrompe a atribuição. Isso faz de never o detector perfeito para casos não tratados.
// Only never is assignable to never.
let x: never;
// x = "hi"; // Error
// Any concrete leftover type fails the same way.
console.log("never catches gaps");Exaustividade como proteção durante a refatoração
Com assertNever em todos os lugares, adicionar um membro à união produz uma lista organizada de erros de compilação apontando exatamente para cada local que você precisa atualizar.
function assertNever(x: never): never { throw new Error("unhandled"); }
type Status = "idle" | "busy";
function render(s: Status): string {
switch (s) {
case "idle": return "Idle";
case "busy": return "Busy";
default: return assertNever(s);
}
}
console.log(render("idle"));Verificação rápida: exaustividade
Teste sua compreensão da verificação de exaustividade.
Recapitulação: exaustividade com o tipo que nunca ocorre
Você aprendeu a atribuir o valor padrão a never ou passá-lo para assertNever para que o compilador obrigue você a tratar todas as variantes. Assim, os casos esquecidos transformam-se em erros de compilação.
function assertNever(x: never): never { throw new Error("unhandled"); }
type Shape = { kind: "circle"; radius: number } | { kind: "square"; side: number };
function f(s: Shape) {
switch (s.kind) {
case "circle": return s.radius;
case "square": return s.side;
default: return assertNever(s);
}
}
console.log(f({ kind: "circle", radius: 5 }));Perguntas Frequentes
A aula “Verificação de Exaustividade com never” é grátis?
Sim — o texto completo de “Verificação de Exaustividade com never” é 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 “Verificação de Exaustividade com never”?
Detecte casos não tratados em tempo de compilação com never. 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 3 de 4.
Quanto tempo leva a aula “Verificação de Exaustividade com never”?
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
- Construindo Uniões Discriminadas
- Restrição pelo Discriminante
- Verificação de Exaustividade com never
- Modelando Máquinas de Estado