headroom.walls.sh · typescript

Claude Code for TypeScript

Claude Code uses tsc as its verifier — the same way it uses pytest for Python or cargo build for Rust. This makes TypeScript an especially clean fit: types are the spec, the compiler is the test, and Claude Code runs both until it's green. This page covers the patterns that work best.

CLAUDE.md for TypeScript projects

Set up persistent context so Claude Code knows your TypeScript configuration from the first prompt:

## Build
- Type check: npx tsc --noEmit
- Build: npm run build
- Test: npm test
- Lint: npx eslint src/ --ext .ts,.tsx

## Conventions
- Strict mode enabled — no implicit any, no non-null assertions (!.)
- Prefer type aliases for unions, interfaces for objects with methods
- All exported functions need explicit return types
- No as any casts — model the type properly or use unknown

Claude Code reads this at session start and uses npx tsc --noEmit throughout the session as the verification step, matching how your CI pipeline works.

tsc as the verifier loop

The most powerful TypeScript pattern with Claude Code: give it a task and tell it to run tsc after.

claude "add types to all functions in src/api/ that currently use any. Run npx tsc --noEmit after each file — fix errors before moving to the next file."

Claude Code writes the types, runs the compiler, reads the errors, fixes them, and runs again — until the file is clean. It doesn't move to the next file until the current one compiles. The compiler output is structured enough that it can fix each error precisely.

The "fix one file at a time before moving on" instruction matters. TypeScript errors cascade — a type error in a base type propagates to every caller. Fixing file-by-file prevents a wall of cascading errors that make it hard to know what to fix next.

JavaScript to TypeScript migration

Migrating a JS codebase to TypeScript is one of the best uses of Claude Code — it's systematic, tedious, and the compiler tells you exactly what's wrong.

claude "migrate src/utils/ from JavaScript to TypeScript. Rename .js to .ts, add type annotations, run tsc after each file. Start with the files that have no imports from other src/ files."

The "start with files that have no local imports" instruction is key — it means Claude Code can type-check each file without needing the full graph to compile first. Once leaf files are typed, dependent files have something to work with.

For a large codebase, do it incrementally:

claude "add allowJs: true and checkJs: true to tsconfig.json, then add @ts-check comments to src/utils/auth.js and fix all errors it surfaces"

This lets you add TypeScript checking to individual JS files without a full migration — useful when you want incremental typing rather than a big-bang rename.

Strict mode migration

Enabling strict mode on an existing TypeScript project generates errors. Claude Code can work through them systematically:

claude "enable strict mode in tsconfig.json. Run tsc, read the errors, fix them file by file. Don't use non-null assertion (!) to suppress errors — model the nullability properly."

Common strict errors and what Claude Code does with each:

Interface and type design

Claude Code is good at designing type hierarchies from a description:

claude "design TypeScript interfaces for a payment system: a base Payment type, then specific types for CreditCard, BankTransfer, and Crypto payments. Use discriminated unions with a 'method' literal field."

Or extracting types from existing runtime shapes:

claude "read src/api/responses.ts — the API returns plain objects. Define proper TypeScript interfaces for each response shape, and update the callers to use them."

For utility type work:

claude "find all places in src/ where we manually pick fields from a type. Replace with Partial, Pick, Omit, or Required where appropriate — run tsc after."

Fixing a wall of tsc errors

When you inherit a codebase with hundreds of TypeScript errors:

claude "run npx tsc --noEmit 2>&1 | head -50. Categorize the errors by type and location. Fix the highest-frequency error category first across all files."

Categorizing before fixing is important — often 80% of errors come from one root cause (a missing type, a wrong interface, a changed API shape). Fixing the root cause collapses the error count faster than fixing files one by one.

React and Next.js TypeScript patterns

claude "add proper TypeScript types to all React components in src/components/ — prop interfaces, event handler types, ref types. Run tsc after each component."
claude "the API routes in pages/api/ use any for req and res. Replace with proper NextApiRequest and NextApiResponse types. Add return type annotations."
claude "add Zod schemas to validate all API route inputs in pages/api/. Generate TypeScript types from the schemas using z.infer."
Session budget note: a large TypeScript migration — hundreds of files, enabling strict mode from scratch — can run 100+ tool calls. Each tsc run across a large codebase counts as one tool call, but reading and editing multiple files per error cycle adds up. Check your session usage before starting a project-wide migration.

Monitor session usage during TypeScript migrations

Headroom — live session usage for TypeScript work

A JS-to-TS migration or a strict mode sweep is exactly the kind of long Claude Code session where you can hit the 5h window mid-task. Headroom shows your session and weekly utilization live in the macOS menu bar — no token, no API key, reads the file Claude Code writes to ~/.claude/.

Install in one line:

brew install patwalls/tap/headroom

Color-coded from calm to amber to red. Know your headroom before you start migrating 200 files.


Refactoring with Claude Code
Writing tests with Claude Code
Claude Code for Python
5-hour session limit explained