Exhaustive with never
- TypeScript course
- Advanced
- Lesson 33/57
- 4 min
Learn exhaustive checking with never.
Exhaustive with never
The never type represents a value that never occurs. In a switch statement, after all cases are covered, the remaining type becomes never. Using this property, we get a compiler error if a case is missing: a non-never type cannot be assigned where never is expected.
function assertNever(x: never): never {
throw new Error("Unexpected: " + x);
}
type Shape = { kind: "circle"; radius: number } | { kind: "square"; size: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.size ** 2;
default: return assertNever(s);
}
}never and narrowing
When the switch covers all cases, in the default branch the remaining union type becomes never. The call assertNever(s) compiles only when s is never; if a case is missing, s is not never and a compile error occurs.
function assertNever(x: never): never {
throw new Error("Unexpected value");
}
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.size ** 2;
default: return assertNever(s); // s: never
}
}Practice Exhaustive area with assertNever
Define an assertNever(x: never): never helper function (with throw new Error("Unexpected") inside). Define the Shape discriminated union type: "circle" (radius: number), "square" (size: number) members. Write an area(s: Shape): number function using switch (s.kind): for circle return Math.PI * s.radius ** 2, for square return s.size ** 2, for default write return assertNever(s);. Print the result via console.log(area({ kind: "square", size: 4 })).
Starter code
// assertNever fonksiyonunu tanımla (never parametre, never dönüş, throw içersin)
// Shape discriminated union türünü tanımla (kind: circle, square)
// area fonksiyonunu switch ile yaz, default'ta assertNever çağır
// square şeklinin alan sonucunu yazdırSample solution
function assertNever(x: never): never {
throw new Error("Unexpected");
}
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; size: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle":
return Math.PI * s.radius ** 2;
case "square":
return s.size ** 2;
default:
return assertNever(s);
}
}
console.log(area({ kind: "square", size: 4 }));Expected output
16
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 How is the never type used in exhaustive check?
- It auto-writes switch cases
- It counts union members
- If a case is missing, assigning to never in the default branch errors Correct answer
- It checks values at runtime
Explanation: The remaining type in the default branch becomes never when all cases are covered; the call assertNever(x: never) accepts only never, so a missing case causes a compile error.
2 assertNever signature
function assertNever(x: ____): never {
throw new Error("Unexpected");
}
function assertNever(x: never): never {
throw new Error("Unexpected");
}
Explanation: assertNever takes never as its parameter; this means it can only be called when all cases are covered, otherwise it gives a compile error.
3 Exhaustive with never parts
| Term | Meaning |
|---|---|
never türü |
represents no value |
default branch |
remaining type after all cases |
assertNever(s) |
errors if s is not never |
Exhaustive check |
compiler catches missing case |