TypeScript vs Flow
This is not a strict comparison, more like a reflection. To me, Flow and TypeScript are same-ish, both not ideal yet better than typeless JavaScript. They are different in many aspects, yet similar for simple use cases.
I'm doing a small experiment with Redux, type system, Finite State Machines, side effects etc. I wanted to try out io-ts, it has type definitions for TypeScript (it is actually written in TS), but not for Flow (they were deprecated before v1). It is possible to update old Flow definitions, but I decide simply to rewrite the application in TypeScript. This post is basically a reflection on the process.
react-scripts-ts
react-scripts-ts comes with tslint instead of eslint and it is configuration is exposed, which is against Create React App philosophy because it supposed to be zero-configuration setup.
Default tslint configuration is too much opinionated. It asked me to sort properties alphabetically. Seriously who has time for this? I want linter to point out footguns, it supposes to help not to make more work for me. I like CRA approach, eslint points some definite errors and formatting is left for prettier.
Linter errors appear as errors, not as warnings. Sometimes those errors "get stuck" - I get into an error state, then I fix it, but the error doesn't go away until I restart the project. I have to disable most of tslint configs, it was an unpleasant experience. And I don't want spent time configuring it, I just want to do some prototyping.
It seems, but I haven't actually measure it, that response cycle (time between I hit save button and changes propagate to browser) is slower than CRA with Flow. Not sure if this due to TypeScript or tslint or react-scripts-ts.
Actually TypeScript vs Flow
While I'm on it. Some people tend to compare TypeScript and Flow. I can't express how same-ish they are to me. I'll explain why - I have this internal dialogue about TypeScript and Flow:
- Flow is built around the idea of soundness, where is TypeScript is built around the idea of "practical" type system (I actually do not buy this idea, it seems they just don't want soundness)
- Yes but Flow have errors in implementation, so it wants to be sound, but actually, it is not. If you want soundness use ReasonML (Ocaml). Also, Flow sometimes gives up type checking, there is so-called uncovered by types code regions and you need to use flow-coverage-report
- Okay, but flow have all those utility types, like
$ObjMap
,$Call
etc. - Yes. TypeScript added a lot of this too recently. See utility-types and flow-to-typescript
- Yet it is not possible to implement
$ObjMap
in TypeScript - Who cares. It is not possible to have exact strings and exact object types from literals
const a = "b";
- In Flow type of
a
is a string, in TS it is"b"
string literal (and it is not possible to doa[0]="c"
) - I heard that exact object types are coming to Flow
- Finally, they copied it from TypeScript
- And TypeScript copied the idea of
typesVersions
from Flow, now we need to wait until this idea will be copied back to flow-typed - Facebook uses Flow, so React is a natural fit for Flow, where is in TS you need to do some tricks
- Okay, but TS also have the biggest number of type signatures
- And we can use some flowgen to convert it to Flow
- Flow has idx
- TS has monocle-ts, io-ts and many more
- TS has compiler flags which are a bad idea because each project will have a different flavor of strictness. Same applies to type signatures, you never know how strict they are.
- TS has a bigger community and more open development cycle. Flow development happens behind the closed doors
And this dialogue goes on and on. So I decided for myself that Flow and TypeScript are same-ish. Both are not sound, both are not ideal. Yet I would choose TypeScript or Flow over plain JavaScript.
Don't get me started about ReasonML/BuckleScript
Photo by Matt Jones on Unsplash
This post is part of the series. Follow me on twitter and github.
Top comments (11)
Thank you for the post. It was interesting to read. I didn't get the
I heard that exact object types are coming to Flow
part. Isn't $Exact<{}> or {||} is an exact object type or am I missing something? It would be fair to notice that flow is written in ocaml which works threeish times faster when analysing a large project.For those who already use flow in a app with redux this lib can come in pretty handy
github.com/lttb/typed-actions
I meant this post medium.com/flow-type/on-the-roadma...
"It asked me to sort properties alphabetically. Seriously who has time for this?"
You can use prettier-tslint to auto-fix many tslint errors.
It's still an absurd thing to enforce as a compiler error, especially by default, and absolutely absurd for a tool based on Create-React-App.
Dan Abramov and I have both urged the author to change the default link setup (per create-react-app-ts #333 ). It looks like there's some open PRs to do that, but no recent progress. Very frustrating.
I actually just tried TS "for real" for the first time today, and I see some potential benefits to using it, but it's hard to recommend CRA-TS as a tool for a beginner with that ridiculously restrictive "lint" setup.
Agreed, enforcing it as an error would be very frustrating especially for beginners.
Can't wait to try this github.com/facebook/create-react-a...
But can you write type-safe react routes with Flow? I don't think so. My vote goes to Typescript.
Reminds me old joke: how I would prefer code snippet
1) github repository
2) gist
3) blogpost
...
997) scanned screenshot in an email
998) written with blue paint on a cow
999) as a YouTube video
Nice write up :)
What about this "Don't get me started about ReasonML/BuckleScript" ?
I like all ideas behind ML-family (OCaml, Elm etc), but the way it is currently done is not yet prefect. It is very promising, but requires a lot of work. This is short version
I have some eggs. I have to get only their yolks for my recipe. I may get them by hand. Or I could use a tool that does the job. But in this latter case I have to watch it ... maybe it can destroy some egg! Boh? Finally I decide to use my hands. Got it?