When we write applications in TypeScript instead of JavaScript, it is evident that we benefit from type safety, saving us from potential bugs.
However, you might have a good reason to refrain from writing your project in TypeScript. For example, migrating an existing JavaScript project might be too much effort. You can still get many of the benefits of TypeScript, though. You might not realise that the more TypeScript knows about your code, even if it's JavaScript, the better your tooling gets.
In this article, we'll dive into what you can do to get more and more of TypeScript's benefits in your JavaScript projects.
The benefits
The main thing TypeScript can do for our JavaScript code is highlight unexpected behaviour. TypeScript infers types across a code base, meaning it can spot when you might, for example, call a string method on a number.
This example may be trivial, but JavaScript will let you write and run that code, eventually discovering that you've caused a runtime error. The TypeScript compiler can analyse that JavaScript, tell you that numbers don't have a function called toUppercase
, and help you catch the bug earlier. However, we need to do some work in our JavaScript project to benefit from this analysis.
Tooling
Before we make any changes to a JavaScript project, it's important to know that TypeScript is already helping your tooling understand your projects better. For example, the TypeScript language service powers VS Code's Intellisense for JavaScript, giving you better auto-complete, and, under certain circumstances, the Sonar scanner will use the TypeScript compiler to understand your JavaScript projects better when analysing them.
Get more out of JavaScript
So, TypeScript is already helping our tooling understand JavaScript better, but what can we do to help TypeScript even more? How can we benefit from TypeScript's type inference, highlight runtime bugs, and get even more out of our tools?
There are a few approaches you can take, some at an individual level and some at a project level, where you will need to get your whole team on board.
Pair program with TypeScript
The easiest way to get more insight from TypeScript is to configure your editor to use TypeScript to analyse the JavaScript you are writing. The following instructions are for VS Code, which has the strongest support for TypeScript. Other editors, like WebStorm, need a tsconfig.json file defined before they will highlight TypeScript issues in your JavaScript, and we will cover those in the following section.
It just takes a comment
VS Code makes this very easy. In any JavaScript file you are writing, add the comment // @ts-check
to the top, and TypeScript will analyse the contents, letting you know with red squiggly lines where things seem out of place. Here, you can see the difference in our original code snippet:
Immediately, you can see that TypeScript has more to offer. It's just waiting for you to give it permission.
Enabling TypeScript checking via a comment is a good way to get a taste of what it offers. The drawbacks are that it only analyses files individually and only when you remember to add the comment. Also, if the rest of your team isn't currently interested in TypeScript, leaving TypeScript-specific comments in files might not go down well.
Flick on the TypeScript switch
VS Code also allows you to turn on TypeScript checking for all JavaScript without changing the source code. Open up the settings and search for Check JS. You will find the setting JS/TS › Implicit Project Config: Check JS.
Enable this setting for the workspace and VS Code will use TypeScript to type-check all the open files in the project. Enable the setting at the user level and VS Code will use TypeScript to check all your projects as you work on them.
I recommend working with the Check JS setting activated. It will teach you things about your JavaScript as you write and maintain it.
SonarQube for IDE is another tool you can use in your editor to highlight issues in your JavaScript as you type. Using TypeScript and SonarQube for IDE alongside each other in your editor can help you learn as you code.
With Check JS activated in your editor, you can work to reduce issues that the TypeScript compiler discovers without worrying about adding config to your application. Also, if it turns out that the TypeScript compiler raises a bunch of issues, they are only visible in your editor and won't break your build.
If you and your team try using TypeScript like this and find it beneficial, you might consider taking the next step and introducing TypeScript directly into your project.
Add TypeScript to your JavaScript project
Introducing TypeScript to your project means that TypeScript becomes a tool that your whole team can use. You can make it part of your build and test process to ensure that the JavaScript you write satisfies TypeScript's constraints, and later, you can even start to add more types, all without changing a single file type to .ts.
Start by installing TypeScript as a development dependency.
Create a tsconfig.json file. I find it easiest to use the TypeScript executable to start this off. Run this command:
Open up the newly generated tsconfig.json file. The default settings here are good when you start a new TypeScript project, but we need to change some options to handle a JavaScript project. Update your tsconfig.json to this:
Important settings include allowJS
and checkJS
. When true, these permit JavaScript to be part of a TypeScript application and then apply type checking to JavaScript files. The checkJS
setting is the equivalent of enabling Check JS in your VS Code settings.
Notably, having a tsconfig.json file with these settings overrides the VS Code settings and enables TypeScript checking in other editors.
I have also included the setting noEmit
because, at this stage, we are not trying to compile our JavaScript; we just want to type-check it. noEmit: true
means that the TypeScript compiler won't try to output anything; it will just report on the JavaScript it reads.
We set strict
to false
for now; getting JavaScript code to adhere to TypeScript's strict mode is quite difficult.
Add a script to your package.json to run the type checker:
Now you can run npm run type-check
and see the results.
Fix missing types
As you haven't been using TypeScript in this project, you will probably have some things to fix. First, if you are working with Node.js then you will need to add TypeScript types for Node.js. This is as easy as running:
Definitely Typed is a community effort to provide types for modules that don't provide their own, and it is very comprehensive. If Definitely Typed has a type for your module, you can install it in your project from the @types
scope.
As an optional addition, you can add types for packages you use that don't provide types themselves from Definitely Typed. If you don't install the types, TypeScript will consider imports from packages as an any
type.
The any
type is TypeScript's catch-all type. It lets the program compile but doesn't give you any further information about the objects you are using. When you add or define types for these packages, TypeScript can then help with autocomplete and highlighting potential issues. I'd recommend installing the types for your dependencies as you come to work on the parts of the source code that use them.
If the types provided aren't correct, there's a great post on Microsoft's TypeScript blog on how to fix them.
Fix your code
Next, you might find TypeScript is reporting some errors in your code. This is what we want!
Any issue raised is a potential runtime bug in your application that TypeScript has now detected. You can see these errors in your editor or when you run the type-check
script. Fixing these errors will improve the reliability of your application. Now TypeScript is part of your project, no further issues like this should slip through.
Add to the build process
Once the type-checking process returns successfully, you may want to add the check to your build process. This will ensure that your code base stays as type-safe as it can be for a JavaScript project.
How you achieve this depends on your existing testing and build process. One option is to run the type-checking process as part of your test suite.
TypeScript can help you write better JavaScript
As we've seen in this post, you don't have to move your project from JavaScript to TypeScript to get the benefits; you can just get the TypeScript compiler to help. Both the Webpack and Svelte projects organise themselves like this. Check out their source code, JavaScript files for code and TypeScript declaration files for the types.
Once you've got to this stage, you might want to make your JavaScript even more safe by adding further types. You can still achieve this without converting the project to TypeScript. Check out this post on typing JavaScript with JSDoc and TypeScript declaration files for more.
Letting TypeScript analyse your code, either in your editor or as part of your project, gives you, and other tools like SonarQube for IDE or SonarQube Server, more insight into how types flow around your application. It can help you write cleaner, more intentional code and lead to more reliable applications.