Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Real-World Union Narrowing Scenarios | Error Handling and Advanced Narrowing
Quizzes & Challenges
Quizzes
Challenges
/
Error Handling and Type Guards in TypeScript

bookReal-World Union Narrowing Scenarios

123456789101112131415161718192021222324252627282930313233343536
// Suppose you receive responses from an API that can return either a User, an Error, or a Loading state. type UserResponse = | { status: "success"; user: { id: number; name: string } } | { status: "error"; message: string } | { status: "loading" }; // A function to handle the API response safely: function handleApiResponse(response: UserResponse) { // Safe narrowing using discriminant property 'status' if (response.status === "success") { // TypeScript knows response is { status: "success"; user: ... } console.log("User ID:", response.user.id); console.log("User Name:", response.user.name); } else if (response.status === "error") { // TypeScript knows response is { status: "error"; message: ... } console.error("API Error:", response.message); } else if (response.status === "loading") { // TypeScript knows response is { status: "loading" } console.log("Loading user data..."); } else { // This should never happen if all cases are handled // (optionally use assertNever for exhaustive checking) throw new Error("Unhandled response status"); } } // Dangers of unsafe assertion: function unsafeHandleApiResponse(response: UserResponse) { // This assertion ignores the real structure at runtime! // If response is not actually a success, this will throw at runtime. const user = (response as { user: { id: number; name: string } }).user; // If response did not have a 'user' property, this will be undefined or throw. console.log("User ID:", user.id); console.log("User Name:", user.name); }
copy

When you process data from external sources such as APIs, you often deal with union types representing multiple possible outcomes. Using type guards and discriminant properties, you can safely determine the actual shape of the data at runtime. This approach avoids dangerous assumptions and ensures that only valid operations are performed on each possible type.

By checking the status property, you allow TypeScript to narrow the type of the response, enabling safe access to properties like user or message. This prevents runtime errors that would occur if you tried to access a property that does not exist on the current variant of the union.

In contrast, using an unsafe as Type assertion tells TypeScript to trust you, even if the value does not actually match the asserted type. This can lead to undefined values, runtime exceptions, and bugs that are difficult to trace. Relying on safe narrowing techniques not only prevents these errors but also improves code maintainability, as refactoring and extending union types becomes safer and more predictable. By avoiding unsafe assertions, you ensure your code remains robust as the shape of your data evolves.

question mark

Which approach is safest for narrowing a union type representing possible API responses?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 3. Capitolo 8

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Suggested prompts:

Can you explain more about how discriminant properties work in TypeScript?

What is an assertNever function and how is it used for exhaustive checking?

Can you show an example of how a runtime error might occur with unsafe assertions?

Awesome!

Completion rate improved to 5.88

bookReal-World Union Narrowing Scenarios

Scorri per mostrare il menu

123456789101112131415161718192021222324252627282930313233343536
// Suppose you receive responses from an API that can return either a User, an Error, or a Loading state. type UserResponse = | { status: "success"; user: { id: number; name: string } } | { status: "error"; message: string } | { status: "loading" }; // A function to handle the API response safely: function handleApiResponse(response: UserResponse) { // Safe narrowing using discriminant property 'status' if (response.status === "success") { // TypeScript knows response is { status: "success"; user: ... } console.log("User ID:", response.user.id); console.log("User Name:", response.user.name); } else if (response.status === "error") { // TypeScript knows response is { status: "error"; message: ... } console.error("API Error:", response.message); } else if (response.status === "loading") { // TypeScript knows response is { status: "loading" } console.log("Loading user data..."); } else { // This should never happen if all cases are handled // (optionally use assertNever for exhaustive checking) throw new Error("Unhandled response status"); } } // Dangers of unsafe assertion: function unsafeHandleApiResponse(response: UserResponse) { // This assertion ignores the real structure at runtime! // If response is not actually a success, this will throw at runtime. const user = (response as { user: { id: number; name: string } }).user; // If response did not have a 'user' property, this will be undefined or throw. console.log("User ID:", user.id); console.log("User Name:", user.name); }
copy

When you process data from external sources such as APIs, you often deal with union types representing multiple possible outcomes. Using type guards and discriminant properties, you can safely determine the actual shape of the data at runtime. This approach avoids dangerous assumptions and ensures that only valid operations are performed on each possible type.

By checking the status property, you allow TypeScript to narrow the type of the response, enabling safe access to properties like user or message. This prevents runtime errors that would occur if you tried to access a property that does not exist on the current variant of the union.

In contrast, using an unsafe as Type assertion tells TypeScript to trust you, even if the value does not actually match the asserted type. This can lead to undefined values, runtime exceptions, and bugs that are difficult to trace. Relying on safe narrowing techniques not only prevents these errors but also improves code maintainability, as refactoring and extending union types becomes safer and more predictable. By avoiding unsafe assertions, you ensure your code remains robust as the shape of your data evolves.

question mark

Which approach is safest for narrowing a union type representing possible API responses?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 3. Capitolo 8
some-alt