🍎 Reason

let ohWaitOneMoreThing = (x) => Js.log(x##foo); let doSomethingElse = (x) => {

Js.log(x);

ohWaitOneMoreThing(x)

}; let doSomething = (x) => {

Js.log(x);

doSomethingElse(x)

}; let s = {"bar": 100}; doSomething(s); // <--- Error here

(Side note: there is no scope hoisting in Reason / OCaml, so the functions have to be declared in inverse call order to make them available to the call point below).

Error:

This has type:

Js.t({. bar : int })

But somewhere wanted:

Js.t({.. foo : 'a })

The first object type has no method foo

Case 5: Number of “any” types in lodash library definitions

Flow: 625

TypeScript: 692

Reason: N/A (there are no bindings for lodash afaik)

I bring this up because many times I hear “but there are no type definitions for Reason”. It’s true. As of today, there are many more types written for existing JavaScript libraries in Flow and TypeScript than there are in Reason (although the last one is progressing at a good pace).

But the truth is that, if these bindings use any extensively as seen above, the comparison is less fair: you could have the best type inference engine on Earth, but these type definitions are worth much less, leading to situations where you think your app is properly typed (“hey, I have 100% coverage! 🎉”) but it’s actually not 😞.

As seen in Case 3, any types can very easily lead to runtime errors. Which is honestly the most frustrating thing that could happen to anyone that has placed a bet on type systems: you invested the time they demanded to add annotations, and still suffer one of the main problems they were supposed to fix (runtime errors).

Conclusions

Flow and TypeScript implementations are very different, but both visions share the proximity to JavaScript. This decision has of course its own challenges: adding types to a language that is so dynamic is no easy feat, it’s amazing to see how powerful both have become over time.

Reason is a whole different language, and its reliance in OCaml (a language with more than 20 years history) definitely plays an important role in the nice features it provides:

An exhaustive and accurate inference engine & type system: many less annotations required but without giving up coverage

Good error messages: this part is mostly due to the Reason team and Jared Forsyth and Cheng Lou in particular

Besides this, it includes many expressive types to define the app data (variants!), and the build process with BuckleScript is impressively fast.

The counterpart is that Reason is much younger than Flow and TypeScript, so parts of the tooling are still being ironed out and the ecosystem is in an earlier stage too.

It also diverges from JavaScript much more than Flow and TypeScript, so it will require at least some initial investment to learn about the differences (much less after version 3 syntax changes). This might be a good or a bad thing: if you have not encountered any issues working with JavaScript and its dynamic types, then you won’t probably see the initial learning step is worth it (but mind you: learning new languages is an investment in your Knowledge Portfolio!).

If you have tried Flow and TypeScript, and you liked the typing experience but are looking for a different approach, I think Reason is at least worth 5 minutes.

In any case, I hope you enjoyed this blog post! Feel free to reach on Twitter or the comments if you have any feedback or suggestions. ✌️