Chapter 38: TypeScript Error Handling

Error handling in TypeScript very calmly, step by step, like we’re sitting together with VS Code open, slowly writing examples, debugging together, and really understanding how TypeScript helps (and sometimes forces) us to handle errors better than plain JavaScript.

Error handling is one of the areas where TypeScript shines the most — especially in 2025–2026 when strict mode + good patterns are standard in serious projects.

1. The core reality in TypeScript (most important sentence)

TypeScript does NOT change how errors are thrown or caught at runtime (everything is still normal JavaScript throw / try…catch)

What TypeScript does change is:

  • How well you can describe what kind of errors might be thrown
  • How strictly you are forced to deal with possible failures
  • How much safety you get around null / undefined / unexpected shapes
  • How cleanly you can model success vs failure in return types

2. Three main kinds of errors you handle in TypeScript projects

Type of error Thrown by whom? How TypeScript helps most Typical 2026 pattern
Runtime exceptions Your code, libraries, network, JSON.parse try…catch + custom error classes Throw AppError subclasses
Expected failures (API, DB…) External systems Union return types (Result<T>) or T | null Result<T> or ApiResult<T>
Developer mistakes (null, wrong type) Your own logic strictNullChecks, noImplicitAny, narrowing Narrowing + non-null assertions sparingly

3. Classic try…catch — what changes with TypeScript

Plain JavaScript:

JavaScript

TypeScript (strict mode):

TypeScript

Modern 2026 best practice — almost never use any for caught errors

TypeScript

4. Custom error classes — very common pattern in 2025–2026

TypeScript

Usage:

TypeScript

Now when you catch → you can narrow very cleanly:

TypeScript

5. The most popular modern pattern: Result / Either style (very common in 2026)

Instead of throwing → return a union that represents success or failure.

TypeScript

Why many teams love this in 2026:

  • No unhandled rejections
  • Errors are values → easier to compose/map/filter
  • Very explicit control flow
  • Works beautifully with React Query, TanStack Query, tRPC, etc.

6. Quick cheat-sheet — error handling patterns 2026

Pattern Return type Best for Throwing?
Throw everything Promise<T> Internal business logic, CLI tools Yes
Throw typed custom errors Promise<T> Most Node.js / backend APIs Yes
Return T nullorT undefined `Promise<T
Result / Either monad Promise<Result<T>> Public APIs, React Query, tRPC-like No
Throw + global handler Promise<T> + middleware Express/NestJS global error middleware Yes

7. Your mini homework (try today)

  1. Create a small async function that fetches something
  2. Wrap it in try…catch with err: unknown
  3. Narrow the error with instanceof
  4. Then rewrite it using Result<T> style
  5. Compare which feels cleaner for your use-case

Which style feels most natural for your current project?

Want to go deeper into:

  • Global error boundaries in Express / NestJS
  • Typing React Query / SWR errors
  • Custom error classes with cause & metadata
  • Handling Promise.allSettled / Promise.all with types
  • Common anti-patterns still seen in 2026

Just tell me — we’ll zoom right into that next! 😄

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *