Skip to content

Migrating JS to TS

Migrating a JavaScript project to TypeScript is not an “all or nothing” process.

You can adopt TypeScript file by file, feature by feature, or even comment by comment.

TypeScript’s design philosophy:

“TypeScript should scale from 0% typed to 100% typed.”

Let’s explore the tools that make this possible.


Incremental Migration Strategy

A successful migration follows a predictable, low‑risk sequence:


Step 1 — Add TypeScript to the Project

Install TypeScript and Node types:

npm install --save-dev typescript @types/node

Initialize a config:

npx tsc --init

This creates a tsconfig.json.


Step 2 — Enable JS Support

In tsconfig.json, enable:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false
  },
  "include": ["src"]
}

What this does

  • allowJs: TypeScript can compile .js files
  • checkJs: TypeScript does not type‑check JS yet

This lets you introduce TypeScript without touching any JS files.


Step 3 — Start Renaming Files to .ts

Pick one file at a time:

utils.js → utils.ts

Fix type errors as they appear.

This is the safest, most common migration path.


Step 4 — Gradually Increase Strictness

Once the project compiles, enable stricter options:

"strict": true

Or enable them one by one:

  • noImplicitAny
  • strictNullChecks
  • noUncheckedIndexedAccess
  • strictFunctionTypes

This lets you tighten type safety progressively.


Step 5 — Remove JS Files Over Time

As more files become .ts, you can eventually disable allowJs and remove JS entirely.


Using allowJs and checkJs

These two options are the key to incremental migration.


allowJs

Allows TypeScript to compile .js files.

Useful when:

  • you want TS to handle bundling/compiling
  • you want to mix JS and TS
  • you want to migrate gradually

checkJs

Enables type‑checking for .js files.

"checkJs": true

This turns JS into “TypeScript with comments.”

Example: JS file with errors

function add(a, b) {
  return a + b
}

add("hello", 10) // ❌ Type error with checkJs

TypeScript infers types even in JS.


When to enable checkJs

  • You want type safety without renaming files
  • You want to catch bugs early
  • You want to migrate slowly
  • You want to keep JS but still use TS tooling

JSDoc‑Based Typing

JSDoc lets you add TypeScript types inside JavaScript files, without converting them to .ts.

This is perfect for:

  • large legacy codebases
  • teams not ready to adopt TS syntax
  • libraries that want to stay JS‑only
  • gradual migration

Basic JSDoc Types

Annotating parameters

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

Annotating return types

/**
 * @returns {string}
 */
function greet() {
  return "hello"
}

Using TypeScript Types in JSDoc

You can reference TS types:

/**
 * @typedef {Object} User
 * @property {number} id
 * @property {string} name
 */

/**
 * @param {User} user
 */
function printUser(user) {
  console.log(user.name)
}

Importing Types in JSDoc

/**
 * @typedef {import("./types").User} User
 */

This is extremely useful for JS projects that want type safety without rewriting code.


JSDoc + checkJs = Typed JavaScript

Enable:

"checkJs": true

Then TypeScript will:

  • infer types
  • validate JSDoc annotations
  • catch errors
  • provide autocomplete

All inside .js files.

This is a powerful migration path for large teams.


Putting It All Together

Here’s a realistic migration flow:


1. Start with JS only

src/
  index.js
  utils.js

2. Add TypeScript + allow JS

"allowJs": true

Everything still works.


3. Add JSDoc types to critical files

/**
 * @param {string} name
 */
function greet(name) {
  return `Hello ${name}`
}

4. Enable checkJs

Now TypeScript catches errors in JS.


5. Convert one file to TS

utils.js → utils.ts

Fix errors.


6. Convert more files over time

Eventually:

src/
  index.ts
  utils.ts

7. Disable JS support

"allowJs": false
"checkJs": false

Migration complete.


Summary

In this lesson, you learned how to migrate JavaScript to TypeScript safely and incrementally:

1. Incremental migration strategy

  • Start with JS
  • Enable TypeScript gradually
  • Convert files one by one
  • Increase strictness over time

2. allowJs and checkJs

  • allowJs: compile JS
  • checkJs: type‑check JS
  • perfect for mixed JS/TS projects

3. JSDoc‑based typing

  • add types without rewriting code
  • annotate parameters, returns, objects
  • import types from TS files
  • ideal for large legacy codebases

This is exactly how real companies migrate to TypeScript—slowly, safely, and with minimal disruption.