█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/TypeScript/Migrating JavaScript to TypeScript
40 minIntermediate

Migrating JavaScript to TypeScript

After this lesson, you will be able to: Migrate a JavaScript codebase to TypeScript incrementally without halting feature work: enable allowJs, rename file by file, and ratchet up strictness safely.

Most TypeScript you meet professionally is not greenfield; it is a JavaScript codebase mid-migration. Doing it well is a real skill: a big-bang rewrite fails, but an incremental, file-by-file migration ships continuously. This lesson is the playbook teams actually use, and a strong interview talking point.

Prerequisites:Decorators and NestJS

Why incremental, never big-bang

Rewriting a whole codebase to TypeScript at once means a giant branch that conflicts with every other change and blocks releases for weeks. The professional approach is incremental: turn on TypeScript alongside JavaScript, convert files one at a time (usually starting at the leaves, the modules with the fewest dependencies, or the files you are already editing), and keep shipping features the whole time. The codebase is a mix of `.js` and `.ts` until it is done, and that is fine.

Step 1: let TypeScript and JavaScript coexist

allowJs and checkJs let TS compile and even type-check your existing JS before you rename anything.

css
// tsconfig.json: the migration starting point
{
"compilerOptions": {
"allowJs": true, // compile .js files alongside .ts
"checkJs": false, // start false; flip to true to type-check JS via JSDoc
"strict": false, // start loose; ratchet up later (see below)
"outDir": "dist",
"target": "ES2022",
"moduleResolution": "bundler"
},
"include": ["src"]
}
// You can add types to plain JS with JSDoc before renaming, getting
// editor checking with zero file renames:
// @ts-check
/** @param {string} name @returns {string} */
function greet(name) { return `hi ${name}`; }

Step 2: rename and type, file by file

Rename a `.js` file to `.ts` (`.jsx` to `.tsx`), then fix the errors TypeScript surfaces. Start with leaf modules (utilities, pure functions) that few things depend on, so each conversion is small and self-contained. For third-party libraries without types, install `@types/<lib>` from DefinitelyTyped, or add a minimal declaration file. Use `any` or `unknown` as a temporary escape hatch to keep moving, but leave a `// TODO: tighten type` so you come back. The goal each day is: more files typed than yesterday, nothing broken.

💡 Step 3: ratchet up strictness, do not start at max

Turning on full `strict` mode on day one of a JS migration buries you in thousands of errors. Instead, ratchet: get everything to `.ts` with loose settings first, then enable strict flags one at a time, fixing the errors each surfaces before enabling the next (`noImplicitAny`, then `strictNullChecks`, which is the highest-value and highest-effort one, then the rest). Each flag is a finite, reviewable chunk of work. Tools like ts-migrate (from Airbnb) can automate the bulk rename-and-annotate pass for very large codebases.

Common mistakes only experienced engineers catch

Attempting a big-bang rewrite in one branch; it never merges cleanly and blocks the team. Go file by file. Turning on `strict: true` immediately and drowning in errors; ratchet flags one at a time instead. Overusing `any` permanently instead of as a temporary, TODO-marked escape hatch, which defeats the point of migrating. Casting with `as` to silence errors instead of fixing the underlying type, hiding real bugs. Migrating low-traffic dead code first; prioritize the files you actually edit and the bug-prone core.

Quick Check

You're asked to move a 200-file JavaScript app to TypeScript while the team keeps shipping. What's the right approach?

Pick the professional strategy.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Decorators, Metadata, and NestJS
Back to TypeScript
Passion Project: Type-First TS Library→