My new best friend TypeScript

TypeScript is not the default choice just yet for JavaScript developers, but it’s slowly getting there. I want to share my journey, and the reasons I don’t ever want to go back. I feel alive again!

Daniel K.
Level Up Coding

--

The past

What I mean by going back? Well, there is a ecosystem around Babel which is currently the primary method for utilizing ES2015+ universally. For type safety, FlowType works almost hand to hand with Babel. I used both of these technologies for quite some time, and it’s not like I was unhappy, but there was some obscure feeling that something is not right.

Let me rewind a little bit more. TypeScript is not exactly a new player, and I remember looking at it some 2+ years ago and I was like: “What? It cannot do this and that?”. It was during the times when ES6 was becoming a thing and Babel was way ahead in feature implementation. TypeScript was lacking in many ways, and type safety did not feel that important to leave the ES6 sweetness behind. Who could give up on fat arrow functions once learned and loved?

The present

Back to the present moment. It was quite a shocking discovery to find that TypeScript was actually keeping up with latest ECMAScript features, and that got me really interested. I wasn’t exactly satisfied by FlowType and a growing hunger for type safety eventually converted me.

Don’t get me wrong — I am not seeking a type safety for reasons of getting fewer bugs in the code. It doesn’t work like that. I believe it was said many times already, but let’s repeat it just for sake of it.

Static type checking won’t ever protect you against runtime errors.

I simply wanted to make my life easier. I am probably getting old and lazy, but it is somewhat annoying to always have to keep checking the source code of some function I’ve written a month ago in order to use it. Not to mention that when there are some deeply nested objects, and I have to figure out where that value is that I need right now. It is so not cool having to do that.

“Blue feathers hanging from an ornamental hoop” by Frankie K. on Unsplash

There are certainly some myths about TypeScript that feel so scary that users would rather avoid it completely. Here are some of them (borrowed from this presentation).

I have to learn a whole new language

Nope, nothing extraordinary to learn, it’s just JavaScript, really.

TypeScript is not interoperable with JavaScript

I am not aware of a single thing in TypeScript that wouldn’t be part of the ECMAScript specification. Please correct me in the comments if I am wrong, but I think it’s pretty safe to say that at least 95% of the TypeScript will be compatible with ECMAScript once you strip down type annotations.

TypeScript is like CoffeeScript or Dart or Babel, or Flow, etc.

That’s actually somewhat true. TypeScript is like Babel + Flow. TypeScript is a compiler/typechecker in a single bundle. It takes care of converting your ES20## code into whatever target you need (ES3 and above). And it’s doing type checking along the way. But most importantly, it works out of the box! There is almost no configuration required — you are good to go.

The tsconfig.json file with a basic configuration of TypeScript.

This might feel similar to Babel when configuring presets and plugins. The difference is you don’t need to install any additional packages, it’s all included in the TypeScript. And with VSCode you don’t even need to look into docs, it will just tell you what you can use there.

You can only use TypeScript in Windows

Nope. TypeScript is platform agnostic. This is probably coming from the fact it’s a product of Microsoft. Well, they certainly have changed ;)

Unit testing will eliminate any need for TypeScript

On the contrary. TypeScript can help you write unit tests. It might be problematic with TDD approach, but otherwise, it is a great asset to have. Just remember, TypeScript won’t save you from runtime errors. That’s why you need both unit testing and TypeScript.

The dirty stuff

“A man with his hands covered with mud” by jesse orrico on Unsplash

Getting started

Are you coming to TypeScript thinking that you need to understand type system before you can use it? Personal advice, do not enable type guards from the very beginning, it can be rather overwhelming. Just go with basic configuration and once you are comfortable that TypeScript is now checking and transpiling your code, read the TypeScript Deep Dive.

I recommend reading that book before the official docs which can sometimes be a bit confusing. For example, they are using let everywhere and it’s easy to get an impression that const doesn’t exist there. Or statements like import m = require("mod") feels as a weird mix of CommonJS and ESM. So yea, read that book first to save yourself some nerves ;)

Linting

I am sure you have learned to love ESLint as it has saved you numerous minutes or even hours of discovering issues which would be hard to track otherwise. How to put this gently…Forget about ESLint!

A type checking alone certainly helps to discover a whole variety of bugs and mistakes. Then there is a TSLint counterpart which covers some missing checks. It’s not that robust in terms of plugins, but you can find most of the important rules from ESLint there. Honestly, I haven’t explored it that deeply yet. As for styling rules, well, just use Prettier and you can dance with joy.

Custom types

Over a short period of time, you will learn to love that everything is nicely typed and your favorite IDE is giving you useful hints all the time. Then you run into some 3rd party library that you really want to use, and you might be wondering how to get types for that. There are basically three scenarios.

* A module is written in TypeScript or has type definition files included — you are done here, no additional effort needed
* There is a @types/* module that you can install (use TypeSearch)
* You have to create a typing stub yourself

In later two scenarios TypeScript will even give you a helpful hint. Just follow it and you are golden.

Typescript giving you advice what to do when declaration for a 3rd module is missing.

It cannot get any easier. Create file eg. vendors.d.ts anywhere in a project, type in the line declare module 'react-acrylic' and you are good to go. This is called an ambient module and it works like a global declaration without a need to import anything, and TypeScript will find it no matter where it is located (in a project folder).

When you get comfortable with the type system, you can slowly expand definitions within your code. Check out my first crude attempt at typing a library. That file simply sits in my project, and whenever I want to use some untyped features, I just add it there. Eventually, I might even publish it to DefinitelyTyped.org.

The reality

Photo by Niketh Vellanki on Unsplash

Personally, I haven’t really tried to convert existing project to TypeScript. That’s probably a major reason why most of the developers are holding back from adopting. What is certain, you won’t run into any issues with the language itself. Everything that you can use with Babel today is available with TypeScript as well. Things will get bumpy when you are depending on some strange/obscure/custom Babel plugin. You might want to check out this article for help with that use case.

In the basic configuration, TypeScript will figure most of the stuff you have there. Everything else will be just untyped and waiting for you to add those types when it makes sense for you. And you surely want to do that. It is the main reason why you are switching, right? What is certain, TypeScript won’t prevent you from running your untyped code unless there are obvious violations, eg. passing number to a function that clearly expects a boolean.

Then you enable various type guards, fix some issues, and perhaps disable them again until you feel ready for another round. Rinse and repeat until everything is nicely typed and safe. Any type annotations that you have added will of course work and yell at you when you violate them.

Don’t try to lie to TypeScript and tell it that this apple is actually an orange and later (runtime) it turns out it is really the apple. Your head might get hurt while hunting for the bug caused by that. If you want a type-safe code, put some effort into figuring out a correct type instead of just spreading any all over the place.

The last thing I want to mention here is that both Babel and TypeScript have a first-class support for the JSX, but with TypeScript you do not need to install anything extra, just enable the option in the config file. If you are a React developer, you are going to be more than fine with this. In a future article, I will focus more on type checking React applications, so stay tuned ;)

--

--

[Ecma|Java]script admirer; ReactJS fan; NodeJS follower; wannabe gamedev; scary monster