Beat the Typescript Monster

Some tips for a peaceful Typescript integration

Romain l'Ourson
We Are Ants blog
10 min readNov 3, 2015

--

I compiled some tips for Typescript usage, because my transition to this !#@*$ tool has been painful in many ways, especially because i’m a N°_°B.

However, the thing revealed itself really useful in the end. I just needed to figure out a couple of things. What follows is not exhaustive, but mainly feedback on how i got it working.

This post was initially intended to be company-internal but we felt it could be useful to a broader audience so i’m putting it on Medium !

SPOILER ALERT: if you’re not interested in JavaScript, what follows might be a bit harsh for you.

P.S: you can also check out the original Gist, much more code-friendly than Medium. I couldn’t integrate it in this article without my titles and code blocks being screwed…

A little bit of context

I work at Ants on a solution to help reduce waste flows towards recycling centers. This is called 6element, is not out yet, and is totally open source.

We mostly use modern web technologies (NodeJS, React, Redux, Material, and others), but there are some things we are not using yet. We are not using ES6 syntax, nor TypeScript, for instance.

I happen to have one colleague, David Bruant, who absolutely wanted us to use those particular tools. I was chosen to try these out on one of our smaller projects.

Let’s do it then !

After a few days trying hard, i finally got to a place where i feel (a little bit) confident. This was difficult mainly for one reason: i tried to integrate more than one new technology at once. Dumb me.

But also because integrating Typescript is not so easy when you’re used to your good old routine.

This is why i wanted to share my experience to some N°_°B lost souls like mine.

Typewhat ?

To keep it short, Typescript is a tool for writing statically typed Javascript. It is useful to avoid silly mistakes you might do with your variables and property names.

In classic Javascript, you’re allowed to do wonderful/absurd things (depending on which side you’re on) like:

Mixing types is something that Javascript users are familiar with, but it is not a good thing, it seems. It is convenient, but generally not a good thing.

Ah, and you write Typescript using ES6 syntax. So i will talk a tiny bit about it too.

My stack

Just so you know, we usually work using these tools:

And for a few days now, Typescript ^^!

Install

If you’re not using npm, you should get it right away.

So you can install Typescript (= TS from now on) by running:

This will give you access to tsc, the TS compiler.

Basic Usage

You now write only .ts files. No more .js.
You can compile your corresponding .js files by running something like:

This should output your .js files no matter the TS errors you might have done, unless you specify it.

There are various options that can be used.
The ones we currently use are:

  • — noImplicitAny: TS is now raising an error every time something’s implicitly declared as any, and that’s harsh -___-
  • — sourceMap: TS generates the source maps for the compiled .ts files. This will allow to have explicit paths to your non-TS errors
  • — target ES5: specifies into which ES version the .js files will be written. Default is ES3, but we use ES5
  • — module commonjs: specifies that you can use modules. We use commonjs, but others are available
  • -w my/path/**/*.ts: this is for watching all files described by the glob associated. It will generate the corresponding .js files.

Usage with browserify

It is technically possible to use Typescript with browserify.
There is the tsify npm package for instance.

From what i could see, the TS errors do make the browserify process crash, which consequently won’t generate your .js files.
This is problematic, because this won’t let you work unless you resolve all TS issues, which, let’s be honest, is not humanly possible when you work with non-TS-friendly modules.

I didn’t find any simple solution over the Internet, so i decided (with a little help from my friend David Bruant) to use gulp instead. Plus, i was going to use gulp anyway !

Usage with gulp

To be able to work with browserify peacefully, and also to allow multiple tasks at once, like watches, you can use the classic gulp solution.

For instance:

  • you watch your .ts files with a TSwatcher which will generate the .js files
  • you watch your client-side .js files with a JSwatcher which will generate your browserify-bundle.js (or whatever you wanna call it).

To use TS with gulp, several packages are available, but gulp-typescript seems excellent.

Then you can write:

WARNING: do NOT use the out option with the gulp-typescript function, as it is shown in their ReadMe.
This is incompatible with module generation (which we use), and will make the TS compiler do funny stuff with your file system…

One full example of TS working with gulp is available in the 6bin repository.

Working with Typescript

From my point of view, there are 2 main advantages working with Typescript: type check of course, and ES6 syntax.

The main problem being that it might take you a while until you get to work fluently again…, even if TS is supposed to issue your .js files whatever happens.

There are some tutorials here and there, but here are some N°_°B insights.

Types

Type verification is the core intention of Typescript. It will issue warnings when variables of the wrong type are used, preventing you from doing crazy shenanigans.

You can declare your variables like this:

The basic types you can use are:

  • boolean
  • string
  • array
  • any, this is for when you don’t care/know
  • void

You can also use a known interface or enum to type a variable, for instance:

When working with functions, you need to declare what types are its inputs and output:

Arrow functions [ES6]

With ES6, anonymous functions (like callbacks) are written in a more compact way. Instead of:

you can write

Ultimately, this can lead to stuff like

Be careful ! If you don’t use braces, the output of your arrow function will have the type of whatever is returned. If you write something like

Import/export modules [ES6]

Importing and exporting modules are a bit different from what we are used to with npm.

Before you would have written

With ES6, you write

You can import/export several stuff very easily:

You can choose to have a default export, this will allow you to get the most important stuff from your module easily, the rest not being exported unless you specifically ask for it with the previous syntax.

You can change the imports names if you need to.

If you need all the exports, you can use *. This is also useful if there is no default export.

More details (but way less fun) on this page.

External modules

The problem
This section is important. We often work with a lot of external modules, because we don’t want to be reinventing the wheelchair again.
When doing so (npm install whatever — save), you will get your package. But TS won’t know anything about it. That’s a shame, because it will keep on saying:

This is ok when you only have a couple of modules, but when you start having thousands of them, it can get messy to sort out what errors are really important to your logic.

Then you need to get TS acquainted with your new module.

Introducing tsd !

With tsd, you can find and install TS definitions that people have written for their modules. And TS will then leave you alone !

You can find definitions using

or by going on this search engine.

You can install definitions with

Installing the whatever definitions means

  • the whatever.d.ts is installed in the typings folder,
  • the tsd.json references whatever.d.ts for future installs,
  • the tsd.d.ts file requires whatever.d.ts for current use

The tsd.json is a configuration file similar to package.json, and the typings folder holds all .d.ts files, which are the actual TS definitions. Your project also gets a tsd.d.ts file which references all subsequent .d.ts files. tsd.json and typings/tsd.d.ts are created running tsd init.

How to use TS definitions ?

Add this line at the very beginning to all your root .ts files :

React

Here’s an example of how you can use TS with React.

What’s important is to define the interfaces of your props and state, and reference them in the newly created component:

even if you won’t be using one of them.

Yeah, i know, i’m not using jsx syntax. Deal with it !

“Shut up and let me work”

You need to know that, even if TS shouldn’t block you from working (it is supposed to generate the .js whatever happens), you might find necessary to tell it it’s annoying.

  • Sometimes a module doesn’t have a TS definition known by tsd. What you need to do is add something like this in your tsd.d.ts file:
  • Sometimes a function from an external module doesn’t have a TS definition with expected signature.
  • Sometimes you really don’t care about the type of the variable you want to use => any

This will issue something like

This is a problem you should really solve, but sometimes it’s not your code and you don’t want to waste time on it.
You can bypass this message either by not using the noImplicitAny option, or by writing something like:

However, it is not recommended to do so, it is just to solve issues that are not directly related to your own code.

What now ?

It’s been a few days now that i use TS, and i have to admit that my first impressions — ”it’s a waste of time, please leave me alone” — are now far gone. All my stupid mistakes, the ones not really relevant to real logic, are instantly spotted by TS, and i can fix them before spending 2+hours trying to find where i forgot to change a variable name. I can focus on real relevant bugs, and that’s soooooo comfortable. I don’t think i’d be able to switch back to before TS

These lines were just a few tips for people like me trying to make Typescript work along with their stack.

This was obviously not a complete tutorial, i still have a lot to learn with TS. I do not have solid good practices to talk about yet.

I’ll be glad if you found something useful in this article. If you have some other tips, feel free to comment, or even write your own article and let me know about it ;)

--

--