Exhaustiveness

Make the compiler prove you handled every case. Assign the value to never in the default branch: never accepts nothing, so if any case is unhandled the assignment fails and the message names the type you forgot.

That is what makes adding a case to a union safe across a large codebase. Add a fourth state and every switch that does not handle it becomes an error, which is refactoring that finds its own work.

Try it

Add the missing case and watch the error clear.

loading editor…

checking…

The empty case was added to the type and not handled. The error names it: Type '{ status: "empty"; }' is not assignable to type 'never'. That message is the compiler telling you exactly what you forgot.

◈ Graded Types

Define a discriminated union called Result with three branches, each carrying a status field: "loading", "error" with a message (string), and "ready" with items (an array of strings). Then write describe(r: Result): string returning "Loading" for loading, the message for error, and the number of items as a string for ready. It must type-check in strict mode without any assertions.

Checked against the compiler, not against how you wrote it. 4 visible and 1 hidden check.

loading editor…
real tsc, strict mode

Mark this lesson complete

Signed in, your progress follows you to every device.

Next: Practice Test →
← Back