Mastering TypeScript's Type Guards for Advanced Error Handling

Learn how to use TypeScript's type guards to write advanced, safe, and readable error handling code even as a beginner.

Error handling is a critical aspect of any application, and TypeScript helps developers write safer and more predictable error handling code. In this article, we'll explore how to use TypeScript's type guards to distinguish between different error types, enabling you to handle errors more effectively and avoid common pitfalls.

Type guards in TypeScript are special checks that allow you to narrow down the type of a variable within a conditional block. This is especially helpful when dealing with errors that can be of any type, such as generic JavaScript "unknown" errors thrown from third-party libraries or API calls.

Let's say you want to write a function that handles errors thrown when fetching user data. You might receive different error types like network errors, API errors with specific properties, or even simple strings thrown as errors.

Here's how you can create custom type guards and use them for better error handling:

typescript
interface ApiError {
  statusCode: number;
  message: string;
}

function isApiError(error: any): error is ApiError {
  return (
    error &&
    typeof error === 'object' &&
    'statusCode' in error &&
    typeof error.statusCode === 'number' &&
    'message' in error &&
    typeof error.message === 'string'
  );
}

function handleError(error: unknown): void {
  if (isApiError(error)) {
    console.error(`API Error ${error.statusCode}: ${error.message}`);
  } else if (error instanceof Error) {
    console.error(`General Error: ${error.message}`);
  } else if (typeof error === 'string') {
    console.error(`Error String: ${error}`);
  } else {
    console.error('Unknown error type');
  }
}

In this example, the `isApiError` function is a type guard that checks if the error matches the `ApiError` interface. Inside the `handleError` function, TypeScript understands the precise type inside each conditional block, meaning you get full type safety and auto-completion.

Using type guards with error handling prevents common bugs like accessing undefined properties on errors or missing important error details. As a beginner, it's a powerful tool to write robust and maintainable TypeScript code.

Here's a quick summary of useful practices when using type guards for error handling in TypeScript: - Always type your error parameter as `unknown` when you expect different error types. - Use custom type guards to narrow down to specific error interfaces. - Use the built-in `instanceof` guard for JavaScript's native `Error` objects. - Handle fallback cases to catch any unexpected or unknown errors.

By mastering TypeScript's type guards, you can confidently handle errors in complex applications and provide clear, user-friendly error messages or recovery options.