VVersions.dev

Fix TypeScript build errors

TypeScript build errors usually trace to one of a few causes: misconfigured module resolution, duplicate or mismatched @types packages, a strict-flag change, or a genuine type mismatch. Diagnose with `tsc --noEmit` before changing config.

WorkflowDifficulty: moderatemedium risk

Last verified · Updated May 22, 2026

A TypeScript build error almost always traces to one of four causes: module resolution that does not match how you bundle, duplicate or mismatched @types packages, fallout from a strict-flag change, or a genuine type mismatch. Reproduce with tsc --noEmit and fix the cause — do not paper over it with any or // @ts-ignore.

Symptoms

  • Build or CI fails with errors like TS2307, TS2345, or TS2322.
  • Editor (tsserver) and command-line tsc disagree about errors.
  • Errors appear only after a TypeScript or @types upgrade.
  • Imports resolve at runtime but TypeScript reports 'Cannot find module'.

Likely causes

  • moduleResolution does not match the bundler (node vs node16 vs bundler).
  • Duplicate @types/* packages resolving to conflicting versions.
  • A newly enabled strict flag (strictNullChecks, noImplicitAny) surfacing latent bugs.
  • Missing type declarations for an untyped dependency.
  • isolatedModules requirements not met (e.g. re-exporting a type without export type).

Diagnostic commands

# Reproduce the exact errors the build sees, without emitting
npx tsc --noEmit

# Print the fully-resolved config tsc is actually using
npx tsc --showConfig

# Find duplicate / mismatched type packages
npm ls typescript
npm why @types/node
npm ls @types/react

Common error patterns

CodeMeaningTypical fix
TS2307Cannot find module 'x' or its type declarationsInstall @types/x, add a declarations.d.ts, or fix moduleResolution
TS2345Argument of type A is not assignable to parameter of type BCorrect the call site or widen/narrow the parameter type — not a cast
TS2322Type A is not assignable to type BFix the assignment or the declared type; check strictNullChecks fallout
TS2305Module has no exported member 'x'Check the import name or a version mismatch in @types
TS1259 / TS2614esModuleInterop / import-shape mismatchEnable esModuleInterop or switch to a named import

⚠ skipLibCheck hides errors inside .d.ts files

skipLibCheck: true skips type-checking of declaration files, including your dependencies'. It is a reasonable default for speed, but if errors vanish only because skipLibCheck is on, a duplicate or mismatched @types package is the real problem — fix that rather than relying on the skip.

ℹ tsserver vs tsc disagreements are usually version skew

If your editor reports different errors than tsc, the editor is probably using a bundled TypeScript while the CLI uses the workspace version. Point the editor at the workspace TypeScript and re-run tsc --noEmit as the source of truth.

AI debugging prompt

My TypeScript build fails. Here is the full output of `npx tsc --noEmit` and `npx tsc --showConfig`: <paste>. For each distinct error code, identify the root cause (module resolution, duplicate @types, strict-flag fallout, missing declarations, or a real type mismatch). Propose the smallest correct fix per group, preferring accurate types over `any` or // @ts-ignore. Flag any error that points to a duplicate @types package and tell me which `npm why` to run.

Safety: Do not suggest blanket any, // @ts-ignore, or disabling strict flags to make the build pass. Each fix must address the underlying cause.

Safe fix workflow

  1. Reproduce with npx tsc --noEmit so you fix what the build sees, not the editor.
  2. Group errors by TS code and fix one group at a time.
  3. For TS2307, decide whether it is a missing @types package, a missing declarations.d.ts, or a moduleResolution mismatch.
  4. For TS2345/TS2322, fix the type at the source rather than casting; re-run tsc.
  5. Run npm why on any type package that appears in two versions and dedupe.
  6. Re-run tsc --noEmit after each group and confirm the error count drops.

Test plan

  • npx tsc --noEmit passes with zero errors
  • Unit and integration tests pass on the fixed build
  • Production build (npm run build) succeeds
  • No new // @ts-ignore or any was introduced to silence an error
  • Editor and CLI report the same result after pointing the editor at the workspace TS

Escalation checklist

  • An error persists only because skipLibCheck is on
  • A dependency ships broken or duplicated .d.ts files you cannot dedupe
  • An error reproduces on one Node/moduleResolution combination only
  • A strict-flag change reveals a latent runtime bug needing a code fix, not a type fix

Official sources

Copy-ready AI prompts

Structured prompts for an AI coding assistant. Inspect first, then execute incrementally, and keep a human in the review loop.

Repo inspection: Repo inspection prompt

You are helping with a TypeScript migration: diagnose and fix TypeScript build errors.

Do not edit files yet. First inspect the repository and report:
1. The exact typescript version in package.json and the lockfile, plus every @types/* package and whether duplicates resolve to different versions (run `npm ls typescript` and `npm why @types/node`).
2. The active tsconfig.json options: strict flags, moduleResolution, target/module, experimentalDecorators, isolatedModules, skipLibCheck, and any flags deprecated in 5.0 / removed in 6.0 (--out, --target ES3, --keyofStringsOnly, --charset, --noImplicitUseStrict).
3. Files using decorators and whether they rely on the legacy (experimentalDecorators) model.
4. The build/typecheck command and whether the project emits with tsc or a bundler.
5. Any // @ts-ignore / // @ts-expect-error suppressions and any JS files type-checked via allowJs/checkJs.

Return: a risk summary, the highest-risk files, a suggested migration order, the commands to run before editing, and any questions that need human confirmation.

Safety: Inspection only. The agent must not modify files in this step.

Works with Claude Code, Cursor, GitHub Copilot.

Test failure debugging: Build-error triage prompt

Triage this failing TypeScript build. Input: the full `tsc --noEmit` output and `tsc --showConfig`. Group errors by code (TS2307, TS2345, TS2322, TS2305, TS1259), explain the root cause of each group, and propose the smallest correct fix — accurate types over casts. Call out any error caused by a duplicate @types package and the `npm why` command to confirm it.

Safety: No blanket any, // @ts-ignore, or strict-flag disabling. Every fix addresses the underlying cause.

Works with Claude Code, Cursor, GitHub Copilot.

Test plan

Commands

  • npx tsc --noEmit
  • npx tsc --showConfig
  • npm run build
  • npm test -- --watch=false

Manual checks

  • Confirm editor (tsserver) and CLI tsc agree after pointing the editor at the workspace TypeScript.
  • Verify that imports flagged TS2307 actually resolve at runtime.
  • Re-check any error that only disappears with skipLibCheck enabled.

Regression risks

  • Casts or any introduced under deadline that hide real type bugs.
  • skipLibCheck masking a duplicate @types mismatch.
  • moduleResolution change breaking runtime resolution for some dependencies.

Acceptance criteria

  • tsc --noEmit exits clean with zero errors.
  • Build and tests pass with no new suppressions.
  • All @types/* packages resolve to a single version.

Frequently asked questions

Why does my editor show errors that tsc doesn't (or vice versa)?

Almost always a TypeScript version mismatch: the editor uses its bundled compiler while the CLI uses the workspace version. Point the editor at the workspace TypeScript and treat tsc --noEmit as the source of truth.

Is it ever okay to use skipLibCheck or // @ts-ignore?

skipLibCheck is a fine speed optimization, but if it is the only thing hiding an error you have a duplicate/mismatched @types package to fix. Prefer // @ts-expect-error over // @ts-ignore so suppressions self-clean, and never use either to mask a real type bug.