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

shell
# 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.

Test failure debuggingAI 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 inspectionRepo 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 removed-in-5.0 flags (--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 debuggingBuild-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.