|
I used both Flow and TypeScript extensively at my last job (coda.io), and through a series of thoughtful discussions and debates, we chose to migrate to TypeScript, even though we had already started using Flow in parts of our codebase. Microsoft did a really good job putting resources behind TypeScript, making sure tooling and IDE integrations are good, and generally getting a ton of momentum going. TypeScript is fast-moving, with bugs fixed and features added at a high rate, and the quality of discussion on the issue tracker is high. Flow, in comparison, was not evolving as fast. Flow touts global inference, which I think means better types when you don't necessarily have annotations on module boundaries, but I mostly care about what's possible in a greenfield or well-annotated codebase. Flow deserves a ton of credit, and Microsoft probably studied it in detail, but I think the advantages are overblown at this point. Take the soundness thing. TypeScript added null-strictness a while ago, and recently they improved function type polymorphism. The reality is that both type systems have limits and you sometimes need to type something imperfectly or use an escape valve ("any"). In most cases, however, TypeScript gives you more sophisticated tools to construct the types you want, so you actually get better types. Maybe TypeScript lacks a theoretical underpinning for soundness, but there's no reason it can't continue to get "more and more sound," with it harder and harder to find good examples of unsoundness. |
At my current job we started a clean slate codebase (react/redux/webpack) beginning of 2016 and had everything typechecked by Flow from the start.
We found Flow to be extremely unreliable and cumbersome to use with not much apparent commitment behind it. As soon as Typescript hit 2.0 we converted the entire codebase (fairly easy to do since the syntax and semantics are very similar') and have been super happy with that decision.
I wholly agree on you remark about soundness vs. tooling. Flow tooling sucked, error messages were cryptic and unhelpful and we ran into obvious mistakes all the time that Flow did NOT catch, without being able to figure out why that was. Editor support was lacking and we just never trusted the typechecker.
Bolting on types to Javascript has tradeoffs and Microsoft did an amazing job of making the right tradeoffs.
There is noticeable effort and momentum behind the project that inspires a lot of confidence in the languages future. It has completely changed the way I write Javascript and I can't imagine going back to an untyped world.
That change was not in rock-solid confidence that TS catches all my errors (although it does a remarkably good job at that), but the sheer productivity improvement types enable (autocompletion, project-wide renaming, all that stuff users of Java or C# IDEs have available to them).