tsc --noEmit --pretty — type-checks without generating output; --pretty formats errors with context lines and color.as any or @ts-ignore — this defeats TypeScript's purpose and creates hidden runtime bugs. Fix the type, don't suppress the error.as any or @ts-ignore as a permanent fix — only as a temporary escape hatch with a tracking comment.tsconfig.json strict and target settings before diagnosing — many errors only appear with specific compiler options enabled.--skipLibCheck is safe — it hides real errors in .d.ts files that surface at runtime.| # | 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] |
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]
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
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
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
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";
}
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");
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
// 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
// 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
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
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
@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
@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;
// 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
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 };
}
!) 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
// 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
strictNullChecks changes everything: With strictNullChecks: true, every Array.find(), Map.get(), and document.querySelector() returns T | undefined. You must narrow before use. [src2, src4]@types/ packages for third-party JS libraries: Libraries written in JavaScript need @types/{name} for TypeScript support. Without them, you get TS2307. Check DefinitelyTyped or use declare module. [src5]skipLibCheck: true hiding real declaration errors: This flag skips type checking in .d.ts files. It speeds up compilation but can hide incompatible type definitions between packages that only surface at runtime. [src2]any in generic constraints: function process<T extends any>(val: T) provides zero type safety. Use unknown for untyped inputs or a specific interface for constraints. [src6]type vs interface: Use interface for object shapes that may be extended; use type for unions, intersections, and computed types. Both work for most cases in TS 5.x+. [src1]# 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 | 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 |
| 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 |
strict: true the default. Projects that rely on loose typing will need to explicitly opt out. Prepare by enabling strict mode now. [src7]strictNullChecks is the highest-impact strict flag: Enabling it on a large codebase can produce hundreds of new errors. Adopt it incrementally using // @ts-expect-error annotations with tracking issues. [src2, src4]typescript.tsdk in .vscode/settings.json points to the project's node_modules/typescript/lib to match CI behavior.