Common Pitfalls and Real-World Exhaustive Checking
12345678910111213141516171819202122232425// Define possible API response types using a discriminated union type ApiResponse = | { status: "success"; data: string } | { status: "error"; errorCode: number } | { status: "loading" }; // Helper function to enforce exhaustive checking function assertNever(x: never): never { throw new Error("Unexpected object: " + JSON.stringify(x)); } // Handle the API response with exhaustive checking function handleResponse(response: ApiResponse): string { switch (response.status) { case "success": return "Data received: " + response.data; case "error": return "Error code: " + response.errorCode; case "loading": return "Loading..."; default: // If a new status is added and not handled, TypeScript will error here return assertNever(response); } }
When you work with discriminated unions in TypeScript, exhaustive checking ensures that every possible variant is handled in your logic. A common pitfall is forgetting to update switch statements or conditional logic after adding a new variant to a union type. If you omit exhaustive checking, TypeScript will not warn you when a new case is missing, which can lead to subtle bugs—such as unhandled states in UI rendering or missing error processing.
Using the never type and an assertNever helper function, as shown above, protects you from these mistakes. When you add a new variant to your union (for example, { status: "timeout" }), TypeScript will immediately report an error at the assertNever call if you forget to handle it in your switch statement. This pattern makes your code more robust and easier to maintain, especially as your application grows and evolves.
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Can you explain how the assertNever function works in this context?
What happens if I add a new status to the ApiResponse type?
Why is exhaustive checking important in TypeScript?
Awesome!
Completion rate improved to 5.88
Common Pitfalls and Real-World Exhaustive Checking
Свайпніть щоб показати меню
12345678910111213141516171819202122232425// Define possible API response types using a discriminated union type ApiResponse = | { status: "success"; data: string } | { status: "error"; errorCode: number } | { status: "loading" }; // Helper function to enforce exhaustive checking function assertNever(x: never): never { throw new Error("Unexpected object: " + JSON.stringify(x)); } // Handle the API response with exhaustive checking function handleResponse(response: ApiResponse): string { switch (response.status) { case "success": return "Data received: " + response.data; case "error": return "Error code: " + response.errorCode; case "loading": return "Loading..."; default: // If a new status is added and not handled, TypeScript will error here return assertNever(response); } }
When you work with discriminated unions in TypeScript, exhaustive checking ensures that every possible variant is handled in your logic. A common pitfall is forgetting to update switch statements or conditional logic after adding a new variant to a union type. If you omit exhaustive checking, TypeScript will not warn you when a new case is missing, which can lead to subtle bugs—such as unhandled states in UI rendering or missing error processing.
Using the never type and an assertNever helper function, as shown above, protects you from these mistakes. When you add a new variant to your union (for example, { status: "timeout" }), TypeScript will immediately report an error at the assertNever call if you forget to handle it in your switch statement. This pattern makes your code more robust and easier to maintain, especially as your application grows and evolves.
Дякуємо за ваш відгук!