Published on

Migrating a Javascript Codebase to Typescript in One Sitting

Authors

This is a brief summary of work that you'll likely run into when migrating an entire javascript codebase to Typescript. Credits to Mike North Sr.Staff Engineer from LinkedIn's UI Infrastructure team for sharing his experiences in recent Typescript workshop.

What not to do

  • functional or behavioral changes at the same time
  • attempt this with low test coverage (its still possible but in your new branch you need to be more strict in manually testing all flows in your app)
  • if you work on an infrastructure team, publish your types for consumers while they're in a weak state

Compiling TypeScript in lose mode

  • allow strict: false in your tsconfig
  • just get your tests start with tests passing

After your app is using typescript

  • Work towards squashing anys in your code.
  • Set a team goal of working towards having your entire code project run in strict mode.
    • strict: true in your tsconfig.json is what you will eventually work towards, but you don't want to enable this until much later. strict:true is a setting which enables all the strict rules in the typescript compiler.
    • instead work on enabling each strict feature on by one in your tsconfig.json. You can about all the strict rules here

Start Migration Scripts

Before you make changes, its highly recommended you create your changes on a different branch! I also don't recommend you do this in one single commit (unless your codebase is really really small), meaning save your progress as you go along.

Making these changes on a different branch is advised since:

  • it allows you to save changes incrementally
    • commit 1: migrated /web folder to typescript and the code is working)
    • commit 2: migrated /tests folder to typescript and the code is working)
  • allows you to revert changes easily
  • allows you to share progress with the team
  • allows you to share your branch with your teammates if you hit a challenge.
# Use `git mv` to rename the files, so that your version control doesnt see
# your file names as deletes and it keeps your history and code review simple and clean.
# ------------------------
# rename all JSX files in src/ to TSX (reactjs example)
find src -name '*.jsx' -exec bash -c 'git mv "$0" "${0%.jsx}.tsx"' "{}" \;
# rename all JS files in src/ to TS
find src -name '*.js' -exec bash -c 'git mv "$0" "${0%.js}.ts"' "{}" \;
# rename all JSX files in tests/ to TSX
find tests -name '*.jsx' -exec bash -c 'git mv "$0" "${0%.jsx}.tsx"' "{}" \;
# rename all JSX files in tests/__snapshots/ to TSX
find tests -name '*.jsx.snap' -exec bash -c 'git mv "$0" "${0%.jsx.snap}.tsx.snap"' "{}" \;
# rename all JS files in tests/ to TS
find tests -name '*.js' -exec bash -c 'git mv "$0" "${0%.js}.ts"' "{}" \;

React Codebases

If your app uses create-react-app as its build system or nextJS then the migration is a lot easier since both of these build systems support typescript transpilation out of the box

References and Resources