Best Practices to Migrate a JavaScript Project to TypeScript
This year I have migrated several JavaScript projects to TypeScript. The latest one is the RingCentral Softphone SDK. I’ve done enough trials and errors and I think I have managed all the essentials for a migration to be successful. Today I’d like to share my experience by writing this article. I will cover the following topics:
- What is TypeScript and why you should use it.
- How to prepare your project for the migration.
- Do the migration and verify it.
TypeScript
First what is TypeScript? TypeScript is an object-oriented programming language developed and maintained by the Microsoft Corporation. It is a superset of JavaScript and contains all of its elements. The last sentence is very important, it implies that TypeScript has wonderful compatibility with JavaScript and that it will not be hard to do the migration.
But why you should use TypeScript? To me, the most convincing reason is that TypeScript can help us avoid painful bugs that developers commonly run into when writing JavaScript by type checking the code. Another very good reason is that TypeScript is nothing but JavaScript with some additional features. So you are not moving away from your favorite JavaScript language. Last but not least, I find that TypeScript is easier to setup than Babel + ES6. I’d been using Babel to write ES6 code for years. But to be frank the setup and maintenance cost is high. Babel is a forever changing technology and I need to keep updating my configurations to use the latest version. In contrast to Babel, that TypeScript setup and configuration is relatively easy. I will post more details about TypeScript setup and configuration later.
It’s noteworthy to mention that one of the reasons TypeScript is becoming so popular is that it offers many solutions to JavaScript’s limitations. Personally I think it is overall quite beneficial to use TypeScript. And if you have never tried TypeScript, I recommend you to have a try. And you can actually start with migrating one of your JavaScript projects to TypeScripts. Please keep reading!
Prepare your JavaScript project
Give me six hours to chop down a tree and I will spend the first four sharpening the axe. — Abraham Lincoln
First of all, make sure that your JavaScript project works. If it is broken right now, migrating it to TypeScript will not magically fix it at all. Run your unit tests, integration tests, system tests…etc if there are any. Try your best to make your JavaScript issue free. Otherwise your project’s original issues will be coupled with the migration caused issues, which makes them very hard to troubleshoot and fix.
Secondly, upgrade all your project’s dependencies. This step is actually optional. But it is always a good idea to upgrade all dependencies to the latest version. I recommend the utility tool yarn-upgrade-all. It can upgrade all the packages in your package.json
to the latest version (potentially upgrading packages across major versions). Don’t forget to test your projects thoroughly after upgrading the dependencies.
Lastly, in order to use TypeScript, you need to setup the TypeScript development environment. There are lots of online tutorials to teach you how to get started with TypeScript. Personally I use google/gts. It could setup your TypeScript environment with just one command: yarn gts init
.
gts is Google’s TypeScript style guide, and the configuration for our formatter, linter, and automatic code fixer. No lint rules to edit, no configuration to update, no more bike shedding over syntax.
I really like its automatic code fixer. And I configured my Visual Studio Code to fix code upon saving. In order to make it work, install File Watcher and create .vscode/setting.json
`in the root of your project with the following content:
{
"filewatcher.commands": [{
"match": "\\.tsx?",
"isAsync": true,
"cmd": "cd '${workspaceRoot}' && yarn gts fix '${file}'"
"event": "onFileChange"
}]
}
Migrate and verify it
With proper preparation, migration is not hard at all. We start by renaming source code files from *.js to *.ts. It is allowed because TypeScript is just a superset of JavaScript. Then we try to compile code from TypeScript to JavaScript by command yarn tsc
. There will be errors, but don’t be panic.
The most common error is Could not find a declaration file for module ‘xxx’
, where xxx
is a dependent library’s name. The solution is straightforward:
Try `npm i — save-dev @types/xxx` if it exists or add a new declaration (.d.ts) file containing `declare module ‘xxx’;`
So if @types/xxx
exists, you just install it and problem resolved, hooray! But not every xxx
has a corresponding @types/xxx
because not every library is built with TypeScript in mind. In such case, you’d have to declare its types locally. First update tsconfig.json
to add the following:
{
...
"compilerOptions": {
...
"typeRoots": [
"src/@types",
"node_modules/@types"
],
...
}
...
}
Then create src/@types/xxx/index.d.ts
with the following content:
declare module 'xxx' {
const xxx: any;
export default xxx;
}
Please note that, the content of index.d.ts
varies. Above is just a default template. It works, but it doesn’t provide any useful information about typings. You may want to take your time to improve the typings.
Every time you fix an issue, re-run the yarn tsc
command. Keep fixing more issues until the command succeeds. Then it’s time to run your unit/integration/system tests. And finally it’s turn to manually run your app to do the final verification. There are actually multiple ways to run a TypeScript project. One way is to compile TypeScript code to JavaScript, then run the app just as you run any other JavaScript apps. Another way is to use the ts-node library which has the ability to compile (on the fly)and run TypeScript code. Once you’ve verified your app, the migration work is considered to be fully done. But of course you can do more testing, the more the better.
Summary
In this article I shared my experience on migrating JavaScript projects to TypeScript. We started with an introduction to TypeScript, followed by detailed instructions to prepare your app for migration. And at last I shared some useful tips to do the migration and verify it.
Please let us know what you think by leaving your questions and comments below. To learn even more about other features we have make sure to visit our developer site and if you’re ever stuck make sure to go to our developer forum.
Want to stay up to date and in the know about new APIs and features? Join our Game Changer Program and earn great rewards for building your skills and learning more about RingCentral!