What Are the Most Common TypeScript Compilation Errors and How to Fix Them?

Type: Software Reference Confidence: 0.93 Sources: 7 Verified: 2026-02-20 Freshness: evolving

TL;DR

Constraints

Quick Reference

# Error Code Message Pattern Likelihood Cause Fix
1 TS2322 Type 'X' is not assignable to type 'Y' ~25% Assigning incompatible type to variable, return type, or property Match the type: change the value, widen the target type, or use a type guard [src1, src5]
2 TS2345 Argument of type 'X' is not assignable to parameter of type 'Y' ~15% Passing wrong type to a function parameter Convert the value, fix the argument, or update the function signature [src5]
3 TS2339 Property 'X' does not exist on type 'Y' ~12% Accessing a property not declared on the type Add property to interface, use type guard, or check spelling [src5, src6]
4 TS2304 Cannot find name 'X' ~10% Undeclared variable, missing import, or missing type definition Import the symbol, install @types/ package, or declare the global [src5]
5 TS7006 Parameter 'X' implicitly has an 'any' type ~8% Function parameter lacks type annotation (with noImplicitAny) Add explicit type annotation to the parameter [src2, src4]
6 TS2532 Object is possibly 'undefined' ~7% Accessing property on possibly-null/undefined value (with strictNullChecks) Add null check, use optional chaining ?., or non-null assertion ! (with caution) [src4, src6]
7 TS2741 Property 'X' is missing in type 'Y' but required in type 'Z' ~6% Object literal missing a required property Add the missing property or mark it optional with ? in the interface [src5]
8 TS2307 Cannot find module 'X' or its corresponding type declarations ~5% Module path wrong, package not installed, or missing @types/ Install the package, install @types/X, or create a declaration file [src5]
9 TS1005 'X' expected ~4% Syntax error — missing bracket, semicolon, or keyword Check for missing }, ), ;, or mismatched template literals [src3, src6]
10 TS18048 'X' is possibly 'undefined' ~3% Variable-level undefined check (stricter variant of TS2532) Narrow the type with an if check or optional chaining [src4]

Decision Tree

START — TypeScript compilation error
├── Is it a TS2XXX error (type/semantic)?
│   ├── TS2322 / TS2345 — Type mismatch
│   │   ├── Primitive mismatch (string vs number)? → Change the value or the type annotation
│   │   ├── Object shape mismatch? → Add missing properties or use Partial<T>
│   │   ├── Union type issue? → Use a type guard to narrow the type
│   │   └── Function return type? → Fix the return statement or the declared return type
│   ├── TS2339 — Property does not exist
│   │   ├── Typo in property name? → Fix the spelling
│   │   ├── Property exists at runtime but not in type? → Extend the interface or use type assertion
│   │   └── Working with union type? → Narrow with type guard before accessing
│   ├── TS2304 — Cannot find name
│   │   ├── Missing import? → Add import statement
│   │   ├── Global (e.g., window, process)? → Install @types/node or add to global.d.ts
│   │   └── Third-party library? → Install @types/{lib} package
│   ├── TS2532 / TS18048 — Possibly undefined
│   │   ├── Optional property? → Use optional chaining: obj?.prop
│   │   ├── Array .find() result? → Add undefined check before use
│   │   └── Known to exist at runtime? → Use non-null assertion ! (last resort)
│   ├── TS2741 — Missing property
│   │   └── Object literal? → Add the property or make it optional in the interface
│   └── TS2307 — Cannot find module
│       ├── npm package? → npm install {package} && npm install -D @types/{package}
│       ├── Local file? → Check relative path and file extension
│       └── CSS/JSON/image? → Add declaration file (e.g., declarations.d.ts)
├── Is it a TS7XXX error (strict mode)?
│   ├── TS7006 — Implicit any
│   │   └── Add type annotation: (param: Type) => ...
│   └── TS7053 — Element implicitly has 'any' type (index access)
│       └── Add index signature: { [key: string]: ValueType }
├── Is it a TS1XXX error (syntax)?
│   └── TS1005 — Expected token
│       └── Check brackets, parentheses, and template literal backticks
└── DEFAULT → Read the last line of the error chain — it identifies the root cause [src1]

Step-by-Step Guide

1. Read the error message structurally

TypeScript error messages are chains. Read from the last line up — the final line identifies the root incompatibility. [src1]

Type '{ name: string; age: string; }' is not assignable to type 'User'.
  Types of property 'age' are incompatible.
    Type 'string' is not assignable to type 'number'.
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              This is the actual cause — age should be a number.

Verify: tsc --noEmit --pretty 2>&1 | head -20 → shows formatted error with context

2. Check your tsconfig.json strict settings

Many errors only appear when strict mode is enabled. Understand what is active. [src2, src4]

{
  "compilerOptions": {
    "strict": true,           // Enables ALL of the below:
    "noImplicitAny": true,    // TS7006: no untyped params
    "strictNullChecks": true, // TS2532: null/undefined checks
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "alwaysStrict": true
  }
}

Verify: tsc --showConfig | grep strict → shows effective strict settings

3. Fix TS2322 / TS2345 — type mismatches

The most common errors. Structural typing means shapes must match. [src1, src5]

// TS2322: Type 'string' is not assignable to type 'number'
let age: number = "25";        // Error
let age: number = Number("25"); // Fixed — explicit conversion

// TS2345: Argument of type 'string' is not assignable to parameter of type 'number'
function double(n: number): number { return n * 2; }
double("5");                    // Error
double(Number("5"));            // Fixed

// Object shape mismatch
interface User { name: string; age: number; }
const user: User = { name: "Alice" }; // TS2741: Property 'age' is missing
const user: User = { name: "Alice", age: 30 }; // Fixed

4. Fix TS2339 — property does not exist

Narrow the type before accessing properties on union types. [src5, src6]

// Error: Property 'email' does not exist on type 'User | Admin'
function getEmail(person: User | Admin): string {
  return person.email; // Error if only Admin has email
}

// Fixed with type guard
function getEmail(person: User | Admin): string {
  if ("email" in person) {
    return person.email; // TypeScript narrows to Admin
  }
  return "no-email";
}

5. Fix TS2532 / TS18048 — possibly undefined

Use narrowing, optional chaining, or the nullish coalescing operator. [src4, src6]

// Error: Object is possibly 'undefined'
const users: User[] = [];
const first = users.find(u => u.active);
console.log(first.name);  // TS2532

// Fixed: null check
const first = users.find(u => u.active);
if (first) {
  console.log(first.name);  // TypeScript knows first is defined here
}

// Fixed: optional chaining + fallback
console.log(first?.name ?? "unknown");

6. Fix TS2307 — cannot find module

Module resolution depends on moduleResolution in tsconfig.json. [src5]

# Missing npm package
npm install lodash
npm install -D @types/lodash
// declarations.d.ts — place in project root or src/
declare module "untyped-package";           // Minimal: types as any
declare module "*.css" {
  const content: Record<string, string>;
  export default content;
}
declare module "*.svg" {
  const src: string;
  export default src;
}

Verify: tsc --traceResolution 2>&1 | grep "untyped-package" → shows resolution path

Code Examples

TypeScript: Type guard patterns for eliminating common errors

// Input:  Values with union types that trigger TS2339/TS2532
// Output: Type-safe access patterns that eliminate compilation errors

// 1. Discriminated union — eliminates TS2339
interface Circle { kind: "circle"; radius: number; }
interface Square { kind: "square"; side: number; }
type Shape = Circle | Square;

function area(shape: Shape): number {
  switch (shape.kind) {
    case "circle": return Math.PI * shape.radius ** 2; // TS knows: Circle
    case "square": return shape.side ** 2;             // TS knows: Square
  }
}

// 2. User-defined type guard — eliminates TS2339 on unknown types
function isUser(obj: unknown): obj is User {
  return typeof obj === "object" && obj !== null
    && "name" in obj && "age" in obj;
}

// 3. Assertion function — eliminates TS2532
function assertDefined<T>(val: T | undefined, msg: string): asserts val is T {
  if (val === undefined) throw new Error(msg);
}

const item = items.find(i => i.id === targetId);
assertDefined(item, `Item ${targetId} not found`);
console.log(item.name); // No TS2532 — TypeScript knows item is defined

TypeScript: tsconfig.json strict migration strategy

// Input:  Existing JS/TS project with no strict mode
// Output: Incremental strict mode adoption without breaking the build

// tsconfig.json — Phase 1: Enable strict gradually
// {
//   "compilerOptions": {
//     "strict": false,
//     "noImplicitAny": true,        // Phase 1
//     "strictNullChecks": false,    // Phase 2
//     "strictFunctionTypes": false  // Phase 3
//   }
// }

// Phase 1: Fix all TS7006 (implicit any) errors
// Before:
function process(data) { return data.value; }
// After:
function process(data: { value: string }): string { return data.value; }

// Phase 2: Enable strictNullChecks, fix TS2532 errors
// Before:
const el = document.getElementById("app");
el.innerHTML = "Hello"; // TS2532: Object is possibly 'null'
// After:
const el = document.getElementById("app");
if (el) { el.innerHTML = "Hello"; }

// Phase 3: Enable strictFunctionTypes
// Catches unsafe contravariance in callback types

Anti-Patterns

Wrong: Silencing errors with as any

// BAD — as any hides the real type error; breaks at runtime [src6]
const data: any = fetchData();
const name: string = (data as any).user.name;
// If data.user is null, this throws at runtime — TypeScript can't help you

Correct: Use proper typing or unknown

// GOOD — type-safe with runtime check [src6]
interface ApiResponse { user: { name: string } | null; }
const data: ApiResponse = await fetchData();
const name: string = data.user?.name ?? "anonymous";
// TypeScript ensures null safety; no runtime surprise

Wrong: Using @ts-ignore instead of fixing the error

// BAD — suppresses ALL errors on the next line, including real bugs [src1]
// @ts-ignore
const result: number = "not a number" + someUndefinedVar;
// Both the type error AND the undefined variable are hidden

Correct: Use @ts-expect-error with explanation (or fix the type)

// GOOD — @ts-expect-error fails if the error disappears [src1]
// @ts-expect-error — third-party lib types are wrong, tracked in JIRA-1234
const result = thirdPartyLib.brokenMethod();

// BEST — fix the actual type
const result: number = parseInt(someValue, 10) || 0;

Wrong: Widening types to avoid errors

// BAD — making everything optional defeats type safety [src5]
interface User {
  name?: string;   // Was required, made optional to "fix" TS2741
  email?: string;  // Was required, made optional to "fix" TS2741
  age?: number;    // Was required, made optional to "fix" TS2741
}
// Now every access needs ?. and every consumer must handle undefined

Correct: Provide the required data or use Partial<T> explicitly

// GOOD — keep the interface strict; use Partial only where needed [src5]
interface User {
  name: string;
  email: string;
  age: number;
}

// For creation forms where fields are filled incrementally:
type UserDraft = Partial<User>;
// For the final validated object:
function createUser(draft: UserDraft): User {
  if (!draft.name || !draft.email || !draft.age) {
    throw new Error("All fields required");
  }
  return { name: draft.name, email: draft.email, age: draft.age };
}

Wrong: Non-null assertion (!) everywhere

// BAD — ! tells TypeScript "trust me, it's not null" — but it might be [src4]
const element = document.getElementById("app")!;
element.innerHTML = "Hello"; // Crashes if #app doesn't exist

const user = users.find(u => u.id === id)!;
user.name = "Updated"; // Crashes if user not found

Correct: Explicit null checks

// GOOD — handle the null case explicitly [src4]
const element = document.getElementById("app");
if (!element) throw new Error("Required element #app not found in DOM");
element.innerHTML = "Hello"; // TypeScript knows element is HTMLElement

const user = users.find(u => u.id === id);
if (!user) {
  console.error(`User ${id} not found`);
  return;
}
user.name = "Updated"; // TypeScript knows user is defined

Common Pitfalls

Diagnostic Commands

# Type-check without emitting (fastest error check)
npx tsc --noEmit --pretty

# Show all errors with file and line numbers
npx tsc --noEmit 2>&1 | head -50

# Count total errors
npx tsc --noEmit 2>&1 | grep "error TS" | wc -l

# Find errors of a specific code
npx tsc --noEmit 2>&1 | grep "error TS2322"

# Show effective tsconfig (see what strict flags are actually on)
npx tsc --showConfig

# Trace module resolution (debug TS2307)
npx tsc --traceResolution 2>&1 | grep "Module name"

# Watch mode — re-check on every save
npx tsc --noEmit --watch --pretty

# List all files tsc will compile
npx tsc --listFiles

# Generate declaration files to check type exports
npx tsc --declaration --emitDeclarationOnly

Version History & Compatibility

Version Status Key Error Behavior Changes
TypeScript 5.8 (Feb 2025) Current Stricter return type checking in conditional branches; require() of ESM in nodenext [src7]
TypeScript 5.7 (Nov 2024) Supported Improved detection of uninitialized variables; better error messages [src7]
TypeScript 5.5 (Jun 2024) Supported Inferred type predicates; better narrowing in control flow
TypeScript 5.4 (Mar 2024) Supported Narrowing in closures; NoInfer<T> utility type
TypeScript 5.0 (Mar 2023) Supported const type parameters; decorator metadata; --moduleResolution bundler
TypeScript 4.9 (Nov 2022) Maintenance satisfies operator (alternative to as for validation without widening)
TypeScript 4.0 (Aug 2020) EOL Variadic tuple types; labeled tuple elements
TypeScript 7.0 (mid-2026, planned) Future Go-based compiler; strict-by-default; ES5 target dropped; AMD/UMD/SystemJS removed

When to Use / When Not to Use

Use When Don't Use When Use Instead
You see a TS error code in compiler output Error is a runtime exception (no TS prefix) Check browser console / Node.js stack trace
Migrating JS to TS and need to fix type errors Error is from ESLint / Prettier (not tsc) Check .eslintrc or Prettier config
Enabling strict mode on an existing project Error is in a .js file with no // @ts-check Enable allowJs + checkJs in tsconfig
Type-checking fails in CI/CD pipeline Error is only in IDE (VS Code) but tsc passes Restart TS Server: TypeScript: Restart TS Server
Third-party library has no types Error is from a build tool (Webpack, Vite) Check bundler config, not tsconfig

Important Caveats

Related Units