Chapter 10.7☕ 16 min read

Debugging TS Errors

TypeScript errors look scary, but they follow a pattern. Read bottom-up, fix one at a time.

01Reading the Bottom Line First

TypeScript error messages can be intimidating. When you first encounter a screen full of red text, it's easy to feel overwhelmed. But TypeScript's error messages are actually incredibly precise and helpful — you just need to know how to read them. The most important rule: READ FROM THE BOTTOM UP.

Think of a TypeScript error like an onion. The error output shows layers of type information — function calls, generic instantiations, conditional type evaluations — all stacked on top of each other. The TOP layers are context: which functions were called, in what order, with what types. The BOTTOM layer is the ROOT CAUSE: the actual type mismatch that caused the error.

If you start from the top, you get lost in the call chain — like reading a biryani recipe from the garnishing step instead of from the rice preparation. You need to start from the BOTTOM — the core problem — and work your way up to understand the context. The bottom line is where TypeScript says "Type X is not assignable to type Y" or "Property Z does not exist on type W." That's your starting point.

Once you understand the root cause, you can trace back up through the error to understand the context. But always start at the bottom. It's the most efficient way to debug TypeScript errors — peel the onion from the inside out, bhai!

02Understanding TS Error Messages

TypeScript error messages follow a consistent structure. Once you understand the anatomy, they become much easier to read.

Error Message Structure:

src/app.ts:42:10 - error TS2322: Type 'number' is not assignable to type 'string'.

  The bottom line is the ROOT CAUSE.
  Lines above are the CALL CHAIN (context).
  42   const result: string = 42;
         ~~~~~~
  Found 1 error. Watching for file changes.

Common Error Types and What They Mean:

// 1. Type 'X' is not assignable to type 'Y'
//    → You're trying to put X where Y is expected
const x: string = 42;

// 2. Property 'X' does not exist on type 'Y'
//    → You're accessing a property that doesn't exist
user.nonExistentProp;

// 3. Object is possibly 'undefined'
//    → You need to check for null/undefined first
if (user) { user.name; }

// 4. Cannot find module 'X' or its type declarations
//    → Missing @types/package or module not installed

// 5. Argument of type 'X' is not assignable to
//    parameter of type 'Y'
//    → Wrong type passed to function
greet(42); // expects string

// 6. 'X' is declared but its value never read
//    → Unused variable — either use it or remove it

The Debugging Process:

  1. Read from the bottom — find the root cause
  2. Check the file and line number — open the file
  3. Understand the type mismatch — what type is expected vs what's given
  4. Fix the code — not with assertions, but with proper typing
  5. Re-compile — check if the error is resolved
  6. Repeat — fix errors one at a time from the bottom
03Error Suppression & Debugging Tools

Sometimes you need tools beyond reading errors. Let's explore error suppression and debugging utilities.

@ts-expect-error vs @ts-ignore

// @ts-expect-error — USE THIS
// "I expect an error here."
// If the error disappears, this
// directive will warn you!

// @ts-ignore — AVOID THIS
// "Shut up, compiler."
// Silently ignores errors forever

// Example:
// @ts-expect-error
const x: number = "hello";
// If a library update fixes this,
// @ts-expect-error will warn:
// "Unused '@ts-expect-error' directive"

// @ts-nocheck — Skip type checking entirely

// @ts-nocheck
// Place at the TOP of a file to
// skip type checking entirely.
// Use for JS migration only!

Using satisfies for Safer Type Checking

const palette = {
  red: [255, 0, 0],
  green: "#00ff00",
} satisfies Record<string, string | number[]>;

// palette.red is inferred as number[]
// palette.green is inferred as string
// satisfies checks the type WITHOUT
// widening the inferred types!

TypeScript Playground

The TypeScript Playground (typescriptlang.org/play) is excellent for isolating and understanding complex errors. Paste your problematic code, see the compiled output side by side, and experiment with fixes.

04Debugging Traps

Common debugging pitfalls to avoid.

Trap 1: Using any to Silence Errorsas any disables type checking completely. Fix the actual type instead.

Trap 2: Ignoring Editor Warnings — Every red squiggle is a potential bug. Fix them before running the code.

Trap 3: Fixing Multiple Errors at Once — Fix one error at a time from the bottom up. The first fix often resolves subsequent errors.

Trap 4: Not Using Hover Information — Hover over a variable in your editor to see its inferred type. This is the fastest way to understand what TypeScript thinks your types are.

05Debugging Cheatsheet

Golden Rule: Read errors from the BOTTOM UP. The bottom line is the root cause.

Debuggig Tools:

@ts-expect-error  // "I expect an error" (preferred)
@ts-ignore        // "Silently ignore" (avoid)
@ts-nocheck       // Skip file entirely (migration only)
satisfies         // Check type without widening

Common Error Quick Reference:

"not assignable"       → Type mismatch
"does not exist"       → Wrong property/name
"possibly undefined"   → Need null check
"cannot find module"   → Missing @types/
"is declared but..."   → Unused variable

Key Rules:

  • Read from the bottom — root cause is the last line
  • Fix one error at a time from the bottom up
  • Hover over variables in your editor to check inferred types
  • Use @ts-expect-error not @ts-ignore
  • Don't use any or assertions to silence errors — fix the type
  • Use the TypeScript Playground for isolated debugging

The Golden Rule: "TypeScript errors are like biryani — the best part is at the bottom! Actually, no — the BOTTOM of a TS error is the ROOT CAUSE. Start there, peel upwards, and fix one layer at a time. Don't be intimidated by the wall of text — it's just TypeScript being thorough and telling you exactly what's wrong, bhai!"

Key Takeaways

  • Read TypeScript errors from the BOTTOM UP — the bottom line is the root cause
  • Fix errors one at a time from the bottom — one fix often resolves multiple errors
  • Prefer @ts-expect-error over @ts-ignore — it validates your suppression assumption
  • Hover over variables in your editor to check inferred types instantly
  • Never use any just to silence errors — fix the actual type mismatch
  • Use the TypeScript Playground (typescriptlang.org/play) for isolated debugging
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase