← Back to TypeScript Course | Chapter 27: Migration from JavaScript | Lesson 6 of 6

Common Migration Issues

Migration can expose implicit any values, incompatible libraries, module differences, and incorrect assumptions in existing JavaScript. Understanding these issues makes conversion smoother.

Core Concept

The most common early migration issue is implicit any everywhere — function parameters and variables with no inferable type default to any unless noImplicitAny is on, silently defeating the whole point of migrating.

Example: Core Concept

typescript
function process(value) { // implicit any without noImplicitAny
  return value;
}
console.log(process(5));

Basic Setup

A basic fix pattern: enable noImplicitAny early even before full strict mode, since it's the single flag that surfaces the most "this needs an actual type" locations across a freshly-migrated codebase.

Example: Basic Setup

typescript
// tsconfig.json: { "compilerOptions": { "noImplicitAny": true } }
console.log("noImplicitAny surfaces every location needing a real type");

Typed Example

A typed example of a classic gotcha: a function that sometimes returns null and sometimes an object will silently type as the object shape unless strictNullChecks is on, hiding a real runtime null-check bug until it crashes in production.

Example: Typed Example

typescript
function findUser(id: number): { name: string } | null {
  return id === 1 ? { name: "Ravi" } : null;
}
const user = findUser(2);
// Without strictNullChecks, user.name would compile but crash at runtime.
if (user) console.log(user.name);

Project Usage

In a real project, third-party libraries without type definitions are a frequent blocker — either a @types/<package> package needs installing, or a local .d.ts declaration has to be hand-written to unblock the migration.

Example: Project Usage

typescript
// npm install --save-dev @types/lodash
// or write a local declare module "untyped-lib" { ... } block.
console.log("Untyped third-party libraries often block migration progress");

Best Practices

Resist the urge to sprinkle // @ts-ignore to silence every migration-era error — each one is a spot the type checker found a real potential bug, and suppressing it just defers the problem instead of fixing it.

Example: Best Practices

typescript
function risky(value: unknown) {
  // Avoid: // @ts-ignore
  // Prefer narrowing the actual value instead of suppressing the error:
  if (typeof value === "string") console.log(value.toUpperCase());
}
risky("hello");
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.