If you haven’t noticed, there are two popular ways of adding types to your Javascript code — Microsoft’s Typescript and Facebook’s Flow.

Both are extremely powerful, gradual, structural, type-systems. They also, look very similar, with almost the same syntax. Almost.

Often developers jumping from one system to the other get frustrated that all the things they learnt no longer work in the same way. And they assume that the features aren’t supported. And so, they do what any modern JS developer would do and vent on Twitter.

But wait, didn’t I just tell you that both type-systems are powerful. Everything you did in one type-systems can probably be achieved in the other.

So, this is an ongoing, incomplete comparison of some of the differences between Flow and Typescript

Flow also doesn’t support any of the other extensions to class syntax that come with Typescript. You see Typescript often claims to be JS with types, but it also brings all these other syntax extensions that have basically nothing to do with JS but look familiar to Java and C# developers. So, you get things like the public and private keywords. I already mentioned implements

Flow skips all these syntax extensions and only supports features in ES6 and many proposals supported by ES7. A simple rule is that if Babel supports a feature, Flow probably supports it too.

Flow is not a compiler, Typescript is. You will usually use Typescript instead of Babel. You will usually use Flow alongside Babel. Again, Flow is much more literally just Javascript with types. Flow understands many of the new, fancy ES6+ features, but all it does is check your code like a super-smart linter. You still rely on Babel to convert your code down to ES5, and also remove your types. Typescript pretty much does it all.

On the other hand, both Flow and Typescript kind of support type-checking without any type annotations at all. Typescript understands JSDoc annotations and do its best with just those types.

Flow, has a special flotate syntax that lets you write ALL your annotation in inline comments, and skip the compilation step entirely. Learning this syntax is easy. Whenever you’re about to write an inline annotation, you can just wrap that in a comment.

var a: number = 1
// becomes
var a/*: number */ = 1

And any other multi-line type definitions etc, can be wrapped in: /*:: ... */

Actually, the enum type is supported by Typescript as well. From what I gather, the only point of an enum is to let you define descriptive variable names while using small numbers. So, in the first example, States is just a collection of 0, 1 and 2, but you get to use names that actually mean something.

Again, Flow skips this, because it doesn’t add features to the language, just types. However, you can achieve something similar with Flow with a little more typing.

const ON = 0
const OFF = 1
const QUANTUM = 2
type States = 0 | 1 | 2

It’s a little more code, but it does exactly the same thing as a Typescript enum

By now, you’re probably thinking “Typescript is great, who needs Flow, Bleh!”. Let me even the odds. In this section that should probably be called, ‘Getting derailed while comparing type systems and deep-diving into a little-known feature instead’

Flow has a few Magic Types that make it possible to write much more accurate types.

This is not a Magic Type per-say, but it makes it possible to write magic types. In flow you can use the * character to tell Flow that it should try to infer the type on its own, and it can be extremely smart.

Here’s an example of using * to write your own magic type. This code is a little far-fetched and you won’t usually need to write it. But when you do need it, nothing else will do.

I’ve probably missed a lot of stuff. But I think I covered the basics. Let me know if I got anything wrong, or missed something important. Any general feedback is also welcome. (@naman34)

There are a few concepts I skipped on purpose, such as co-variance vs contra-variance. This is because I’m not sure about all the details about that. I just know Flow and Typescript have different strategies for dealing with sub-types.