TS has a concept of "freshness" which catches some of these mistakes when you construct y right in the arguments of x, but it gets easily broken by accident and without a warning.
2. Nominal types, so you can have for example "Id" type that is a number but not to be mixed with other numbers, you can't just call a function that expects an Id with literal 42. Classes are nominal too, which I think is a solid choise.
4. Local call site type inference of function argument types, so you can have some helper functions within a file that you don't need to explicitly annotate, and Flow will happily infer types based on how you call it.
5. Performance has gotten prerty good with recent versions, to the point where I suspect it's faster than TS. I don't have any hard data on this though.
Even though in many many ways Flow is worse than TS, we have still stuck with it, and that's only like 80% because it'd be s huge undertaking to make the switch. 20% is because some of these features are actually nice :)
I would also like nominal types in TypeScript, but one issue is that it might open a can of worms that is antithetical to one of TypeScript’s main design goals: that a change in the typing of a program should not be able to modify behavior.
If you add nominal types, some people might expect them to be boxed, and thus be able to reflect on types at runtime. So I assume that TypeScript maintainers have made a design decision that users should have to “self-box” nominal types.
>2. Nominal types, so you can have for example "Id" type that is a number but not to be mixed with other numbers, you can't just call a function that expects an Id with literal 42. Classes are nominal too, which I think is a solid choise.
Structural typing is one of the best features of TS in my opinion, I like it in general but it's a better fit for JS ecosystem.
Structural typing is a sane default in JS land, but there are times that you really really want nominal typing and its complete absence from TS kind of hurts.
for what it's worth you can totally fake nominal typing in a hacky way through a sort of shiboleth key. You say "this type has `____type: 'foo'`, and on constructions of the object you just cast (or hell, just put the key in!), and you're off to the races.
This is far from perfect, but when you're working with very tricky code and want to be sure, you at least have the option
Yeah, for modeling with types, you frequently want nominal types (e.g. you want to make sure that a certain types always means “the data has passed through such and such a function). Flow’s combination of structural and nominal types seems better to me than TS’s pure structural system.
I worked on a project that used used Flow 3 years or so ago. Unless something has changed since then, it was crazy fast. It took a couple of seconds from typing a command in the console to type-check the project to getting the results; whereas running tsc on a project I am working on now takes dozens of seconds to complete. This is my deepest regret of leaving Flow.
Hmm, TS is super fast today for me, at least in all the cases that matter for me. I rarely run a full project typecheck because I can trust my IDE to show me errors instantly.
Speaking of IDEs (well, VSCode), one minor annoyance is that I have to manually restart the typescript language server from time to time; otherwise VSCode doesn't pick up the types properly. Don't know which part of the toolchain is to blame for this.
it has some nice features that ts doesn't have: opaque types (can be done by nominal tying in ts). More stringent JSX, but only slightly.
I think that's it these days. Flow used to have (slightly) more features but now TS has way more already and even more to come. The Flow people moved on to Recript, or whatever name they call it these days.