{{announcement.body}}
{{announcement.title}}

How to Easily Migrate From JavaScript to TypeScript

DZone 's Guide to

How to Easily Migrate From JavaScript to TypeScript

In this article, we discuss how to easily migrate from JavaScript to TypeScript to reap the benefits of a flexible but strongly-typed language.

· Web Dev Zone ·
Free Resource

If you’ve been working in the software development industry (especially if you're doing a lot of frontend work) in the past couple of years, it’s most likely you worked, or still do, on a project in JavaScript. And by now, you’re more than tired from it. Therefore, in this article, I would like to talk about how to migrate from JavaScript to TypeScript.

Don’t get me wrong, JavaScript is an extremely flexible and easy to learn and use language, with one of the biggest communities out there. But, it also comes with a bunch of pitfalls you eventually end up running into, like it’s loose typing that can result in “odd” behavior. And there are some really interesting languages that transpile to JS and can be used on top of it, such as Dart, Elm, or TypeScript, just to name a few.

You may also like: New Features in TypeScript 3.7 and How to Use Them.

How to Easily Migrate from JavaScript to TypeScript

It’s much simpler to abandon JS when starting a new project, where you don’t have to worry about things like retro-compatibility, or an app’s maintenance in production. In that case, you can try many alternatives, and choose the one you like the best.

Nevertheless, if you must continue to work on an old project, you can begin to migrate from JavaScript to TypeScript, in a “slow” manner, file by file, or adding TypeScript only in the new files you create.

This is possible because TypeScript is a superset of JavaScript, meaning that any JS code is also valid TS code (assuming the TS configuration is set to be compatible with it).

Now, I will present a simple way to add TypeScript to a project, without the need to modify our configuration of webpack, gulp, or whatever our build system is.

Assuming you use npm as a package manager in your project, first thing we need to do is to add TypeScript as a dependency (if not, you can install it globally):

Java




xxxxxxxxxx
1


1
npm install --save-dev typescript



Note: depending on what your project is, you might also want to install “@types” for other libraries you have dependencies on. For example, if you have a react-redux project, you might need to install the following:

Shell




xxxxxxxxxx
1


 
1
npm install --save-dev @types/node
2
npm install --save-dev @types/react
3
npm install --save-dev @types/react-dom
4
npm install --save-dev @types/react-redux
5
npm install --save-dev @types/react-router-dom



After that, we need to add a tsconfig.json file at the root directory of the project. That file contains compiler options needed to convert TS to JS. In order to have the least issues, use the following configuration to make JS code compatible with TS:

JSON




xxxxxxxxxx
1
10


 
1
{
2
 "compilerOptions": {
3
     "module": "commonjs",
4
     "sourceMap": true,
5
     "jsx": "react"
6
 },
7
 "exclude": [
8
     "node_modules"
9
 ]
10
}



Note: You might need to change some bits based on your project. More on that here.

Now, add the following script in your package.json:

JSON




xxxxxxxxxx
1


 
1
"tsc:w": "tsc -w"



And run it. It will run a watcher that transpiles all .ts (or .tsx) files into regular .js files. Also, it will generate these files at the same path that of original; therefore, all imports and all build processes you might have will work as before, since the .ts files are completely ignored, and the result of the transpilation is used instead. The generated file structure has the following structure:

Java




xxxxxxxxxx
1


 
1
file.ts
2
 ├── file.js
3
 └── file.js.map



Now, all we need to do is to create our first ‘.ts’ file by changing the extension of an existing one that we want to migrate to TypeScript. Alternatively, we can also create a blank file to start working in our application.

This does not bring much change. We still can put normal JS code and get no help from what TypeScript has to offer. In order for TS to force us to actually type our code, we need to change the tsconfig.json file. In particular, we will focus on two compiler options that will force our code to be actually typed:

JSON




xxxxxxxxxx
1


 
1
"noImplicitAny": true,
2
"strictNullChecks": true,



Let’s imagine we have a simple mortgage simulator that tells the user if, given his financial situation, a mortgage is viable or not. For that, we will have a function that will retrieve somehow the savings user has:

TypeScript




xxxxxxxxxx
1


 
1
function getSavings() {
2
 //returns savings
3
 }



And a function to decide if a mortgage is feasible:

TypeScript




xxxxxxxxxx
1


 
1
function concedeMortgage(homeValue) {
2
     const savings = getSavings();
3
     return savings / homeValue > 0.2;
4
}



But, to make it actually work, we would need to check if the input exists. And also if it’s a number or not. The same applies for the return value from getSavings, since we don’t know the return type of that function either. Therefore, our code could end up looking something like this:

TypeScript




xxxxxxxxxx
1


 
1
function concedeMortgage(homeValue) {
2
     if(!homeValue || !parseFloat(homeValue)) return false;
3
     const savings = getSavings();
4
     if(!savings || !parseFloat(savings)) return false;
5
     return savings / homeValue > 0.2;
6
}



This looks quite terrible.

But, if we activate the noImplicitAny compiler option, it would no longer be necessary to check if the input value and the return from getSavings are numbers, so the function could look something like this:

TypeScript




xxxxxxxxxx
1


 
1
function concedeMortgage(homeValue: number): boolean {
2
     if(!homeValue) return false;
3
     const savings = getSavings();
4
     if(!savings) return false;
5
     return savings / homeValue > 0.2;
6
}



This is an improvement, since the compiler can help us to avoid some mistakes and typos, not allowing us to call the function with a string for example:

TypeScript




xxxxxxxxxx
1


 
1
concedeMortgage("foo")  // ERROR! Argument of type 'foo' is not assignable to parameter type 'number'



Unfortunately, null and undefined are still in the domain of every type, therefore it would be possible to do this:

TypeScript




xxxxxxxxxx
1


1
concedeMortgage(null) // Still works



To fix that, we need to activate the other option in the tsconfig.json file we mentioned, strictNullChecks.

Now, doing the call to the function with null, would end up getting caught by the compiler:

TypeScript




xxxxxxxxxx
1


 
1
concedeMortgage(null) // ERROR! Argument of type 'null' is not assignable to parameter of type 'number'



That means that we don't need to check for null types, which simplifies the logic to something like:

TypeScript




xxxxxxxxxx
1


 
1
function concedeMortgage(homeValue: number): boolean {
2
     const savings = getSavings();
3
     return savings / homeValue > 0.2;
4
}



This is just a small glance at what TypeScript can give you if you migrate your project from plain JS to it.


Further Reading

Topics:
javascript, node, npm, software developers, tutorial, typescript, web dev

Published at DZone with permission of Roman Predein . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}