- Simple module system where you don't need to deal with named vs default imports and all the weird bugs getting them mixed up can bring
- TypeScript's inherent JS-like nature can pop up subtle bugs like forgetting to type a pair of parentheses:
function isSupported(): boolean {
return false;
}
function test() {
console.log(true && isSupported); // true
}
Or doing object/array indexing and forgetting to handle the case of 'undefined' because TypeScript doesn't enforce that. Or how any typings from before version 2 are suspect because they were written with the assumption that every type can be implicitly nullable. There are lots of these little footguns all over the place.- Higher-quality bindings: more stuff captured at the type level, you're not left to deal with bindings full of 'any', 'object', and 'function'
It's not even just about safety though. One of the biggest productivity drivers in Reason is its iteration speed–the compiler is so fast that you can try out changes basically as fast as you can save the file. And there are other things, like how all modules are implicitly available in scope, so you don't need to manage a 'wall of imports' at the top of every file before you can actually get to the code itself.
FWIW this was just fixed in TypeScript 3.9.
EDIT: I just tried in the TypeScript Playground (v3.9.2), it's actually rather worse than I thought, it prints not 'false' but the actual function itself as a value...
- It's Usable
- It Has Full Type Safety
Pick two.
I think the TypeScript is aware of the tradeoffs, have chosen the first two, and the result is a great developer/IDE experience for JavaScript programs (props!). Reason chooses the last two and creates a great experience for writing very safe web apps.
Edit: Apparently the functionality already exists as of 3.7. The update in 3.9 was to add it to ternary operations as well
Pattern matching has been by far my most favorite feature as someone coming from TypeScript: https://gist.github.com/peterpme/10840585ddced15a7f4ecd05394...
The ability to use "constants" that are inherently typed mean less mistakes and a better path forward for handling your application state.
Refactoring with this in mind, becomes a lot safer. For example, if I had a reducer that needed a new action, I would add that action to the `type`. The compiler would then tell me every place I needed to handle that case.
2."Implicit" Types (types that don't get in the way)
I don't need to type everything like I would in TypeScript. ReasonML already figures all of that out for me. I _can_ add the type if I want (for readability purposes). There is no such thing a `any` or any type of escape hatch for that (this can be frustrating at first) but once you get it, you write code more confidently.
3. React & Refactoring
Say I've got a bunch of React components I need to refactor. Reason types both the prop key and value. If I remove a prop or change that prop's data structure, I'll immediately know all the places I need to make that change.
I know some folks may roll their eyes when they read this, but after using both Reason and TypeScript at Draftbit, I strongly believe it's a competitive advantage. The stuff we ship in Reason just doesn't break.
But you do have to have the compiler give the thumbs up before it will compile the reason side of the project.
You can also checkout the tutorial for slowly converting a single file here, although I find myself doing this sort of thing very rarely: https://reasonml.github.io/docs/en/converting-from-js
ReasonML (OCaml) natively supports pattern matching, variants (Sum types), polymorphic variants, smart constructors, abstract data types, recursive types, and modules.
When you know how to use all of these features, you can prevent a remarkably large surface of bugs from ever compiling. As a new user, the first feature that will probably bring a smile to your face is pattern matching with variants.
If you are interested I highly recommend the book "Learn Type-Driven Development"
I used to use IntelliJ, and there was a solid plugin for that as well.
ReasonML's compiler is way faster than Typescript's.
In terms of compiler speeds, Draftbit has 1,000 ReasonML components and about 100 TypeScript files.
I can safely build AND type the entire ReasonML project before TypeScript returns the type results in watch mode.
But to answer your actual question: The current standard (reason-language-server) does simply wrap the compiler, and it's more than fast enough, but the community is working on a new merlin-based language server (ocaml-lsp) which does support partial compilation.
I would add that the types from Reason are much "smaller" and concise, Option type or Result type and the immutability of Records/Objects creates an environment of safety that I don't have it in TypeScript.
TS fixes some of JSs issues, but many it cannot fix by still being a super set of JS.
Reason is similar (enough) to JS syntax-wise, while not having to deal with it's quirks. This is huge for me.