The never Type and assertNever Pattern
When working with discriminated unions in TypeScript, it is essential to ensure that every possible variant is handled in your logic. The never type and the assertNever pattern are powerful tools for enforcing exhaustive checks, especially in switch statements. By leveraging these, you can catch missing cases at compile time, preventing subtle bugs that might otherwise appear when new variants are added to a union type. This practice is especially important for code maintainability and safety as your codebase grows.
123456789101112131415161718type Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number }; function assertNever(x: never): never { throw new Error("Unexpected object: " + x); } function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius * shape.radius; case "square": return shape.side * shape.side; default: return assertNever(shape); // Compile-time error if a new kind is added and not handled } }
In this example, the assertNever function takes a parameter of type never. If the switch statement is missing a case for a new variant of the Shape union, TypeScript will flag a compile-time error at the call to assertNever. This ensures that all possible variants are considered, making it much less likely to overlook a case when the union is extended. Exhaustive checking using never and assertNever is critical for maintainability because it forces you to update all relevant logic whenever your union types evolve, reducing the risk of runtime errors caused by unhandled cases.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Awesome!
Completion rate improved to 5.88
The never Type and assertNever Pattern
Swipe um das Menü anzuzeigen
When working with discriminated unions in TypeScript, it is essential to ensure that every possible variant is handled in your logic. The never type and the assertNever pattern are powerful tools for enforcing exhaustive checks, especially in switch statements. By leveraging these, you can catch missing cases at compile time, preventing subtle bugs that might otherwise appear when new variants are added to a union type. This practice is especially important for code maintainability and safety as your codebase grows.
123456789101112131415161718type Shape = | { kind: "circle"; radius: number } | { kind: "square"; side: number }; function assertNever(x: never): never { throw new Error("Unexpected object: " + x); } function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius * shape.radius; case "square": return shape.side * shape.side; default: return assertNever(shape); // Compile-time error if a new kind is added and not handled } }
In this example, the assertNever function takes a parameter of type never. If the switch statement is missing a case for a new variant of the Shape union, TypeScript will flag a compile-time error at the call to assertNever. This ensures that all possible variants are considered, making it much less likely to overlook a case when the union is extended. Exhaustive checking using never and assertNever is critical for maintainability because it forces you to update all relevant logic whenever your union types evolve, reducing the risk of runtime errors caused by unhandled cases.
Danke für Ihr Feedback!