Migrating From JS

Move a Codebase One File at a Time

Migrating From JS

You don't have to convert everything at once. TS lets you mix JS and TS files and tighten checks over time.

4 min read Level 2/5 #typescript#migration#javascript
What you'll learn
  • Set up TS in an existing JS project
  • Convert files incrementally
  • Use `// @ts-check` and `// @ts-expect-error` as bridges

A large JS codebase doesn’t get converted in a weekend. TS is designed for gradual migration — you can ship a half-converted project that still benefits.

Step 1 — Install and Configure

npm install --save-dev typescript
npx tsc --init

Edit tsconfig.json to start loose:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "allowJs": true,
    "checkJs": false,
    "strict": false,
    "noEmit": true
  },
  "include": ["src"]
}

allowJs: true lets TS read your .js files. strict: false keeps the noise low while you migrate.

Step 2 — Type-Check JS

Add JSDoc to your most important .js files and turn on // @ts-check:

// @ts-check

/**
 * @param {number} a
 * @param {number} b
 * @returns {number}
 */
function add(a, b) {
  return a + b;
}

You get most of TS’s value without renaming a single file. Use this to find your bug-rich files early.

Step 3 — Rename .js.ts

Pick a leaf file (something nothing else imports type-aware from) and rename it. Add types. Fix the errors. Move on.

Step 4 — Tighten Over Time

Once most files are .ts, gradually enable strictness:

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

Each flag at a time. The error list shrinks as you fix.

Bridging Tools

  • // @ts-expect-error — silence a known error and fail the build if it stops being an error. Great for tracked tech debt.
  • // @ts-ignore — silence forever. Avoid.
  • any — escape hatch when nothing else works. Add a TODO.

Don’t Convert Bad Code

If a file is genuinely a mess, fix it first, then convert. TS won’t make tangled JS into clean TS — you’ll just spend a day typing every any cast.

Order of Migration

A reasonable order:

  1. Domain types — your data model, in one place
  2. Utilities — small leaf modules
  3. Server endpoints / pages — outer layer
  4. Components

By that point, you have a fairly typed codebase, and the remaining .js files are obvious.

Up Next

Where to go next — references, resources, deeper topics.

Going Further →