Hacker News new | ask | show | jobs
by Karnickel 3080 days ago
I've been a heavy user of Flow for - two years now? I also occasionally use TypeScript. I don't contribute to the code (in the Flow case, I don't speak OCaml, I contributed a bit to the type library and the online docs; in the case of TS, I don't use it enough), but I write a bug report each time I find an issue.

I've been looking at the issues list very often, mostly out of curiosity to see what the problems are that people have (both Flow and TS) and to see which project is better at solving problems.

TypeScript seems to win hands down. Their ratio of closed tickets to open tickets is far better than that of Flow:

- TypeScript: 2,515 open, 12,716 closed -- https://github.com/Microsoft/TypeScript/issues

- Flow: 1,830 open, 2,467 closed -- https://github.com/facebook/flow/issues

I have to assume they mostly close issues after solving them - it is not unheard of that issues are closed merely because they've been lying around for a few months without any updates (definitely happens for Flow).

I prefer the approach of Flow, but I think the actual developers are not present at all on Github, most answers come from other users. There are very few actual solutions to issues that are raised. The list of issues grows ever larger. Flow does make progress, and it's not even bad. Every 10-15 days we get a new release and I'd say the progress is quite okay. What went really well the last 12 months was IDE integration for Flow in the case of Jetbrains Webstorm (for TS the situation always looked good), as of now, latest Webstorm version, it's actually usable. I still get too many Flow server crashes though, which may be due to my platform (Windows 10), not sure. However, it's now automatically restarted most of the time.

A TypeScript anecdote: I filed an issue that a "Member" closed as "works as intended" after a few comments back and forth (but it was clear right away that this would be the end). I filed it again - this time Anders Hejlsberg himself responded and acknowledged the issue (it was kind of fundamental and not just something unimportant), and it got fixed. So here too you need a bit of luck to get through to someone who actually understands the subject well enough (including knowing when they don't understand it, if that first guy had just stopped handling my issue it would have been fine). But that's the price of using a popular large project, so this is not a complaint - just an anecdote, okay?

What I do get for myself after following the two type systems for well over two years is that there are LOTS of restrictions. Just read some of the issues in both Github repos, it's really interesting.

I find the whole situation very unsatisfying. It is clear - when you actually use it heavily for a big project for a longer period - that a type system on top of Javascript is very difficult to maintain. LOTS of unsolved cases and issues. You definitely have to adapt and use only the subset of Javascript and the type system that works. I validate an object manually and I still have to do an "any" cast in Flow because Flow does not recognize that my `if` statement secures the type. Or I have to insert such `if` statements even though from the context it is perfectly clear what I get there. For example, any inner functions, e.g. when using map, filter, reduce, loses the type if you use a variable from the outer scope. Or you have to use a lot of additional `const` for object properties even though you don't change the object - but the type checker is not intelligent enough to recognize that. You definitely write different code - and while that may seem okay there are plenty of cases where it really is objectively unnecessary, but you have to do it to satisfy the type system.

On the bright side, once you get your code all "type system ready" you really do find bugs - even if it's just a few. Also good is that I now get much better autocompletion suggestions in the IDE. There's a reason why I (as project head) still insist on us using Flow even though I say "WTF?" often enough. It does cost a significant amount of time though - a very significant amount. I've been willing to do it because of the kind of project, which is going to be a very low-level building block for later larger projects, so it is worth spending a lot more resources on getting it right compared to a project that's on a top layer, on which nothing else depends.

Still, overall I have very mixed feelings and I see the type checkers (both TS or Flow, or any other that could be written) on top of a language that doesn't have types as a kludge that does not look like a long-term solution. There is too much friction between the language and the type system.

7 comments

The question is why don’t they collaborate and unify the efforts?

It seems it should only not happen for a handful of reasons.

For example, if there were real intractable philosophical differences, if someone risks losing strategic advantage, or if competing is driving better results than collaboration could.

Yet it’s not obvious to me how any of these are true.

For many projects unification wouldn’t make sense by a mile even for reasons not listed here.

I don’t even see how the existing skill sets are tragically different, say like the the skill sets are so different for Linux/Windows admins who could never master the other’s job in a week.

In this case maybe there are reasons for separate projects but are they really super compelling?

Imagine the (potential) upsides of having more resources, less confusion, and more comprehensive tooling support.

To me they are both useful projects but I don’t see any fundamental advantage of one over the other that would make me lose sleep if everyone rallied behind a single effort.

The JS type system world has benefited a lot from NOT having a monopoly. When Flow started gaining some traction, the whole "handle nulls properly" thing was a huge. During that time, the TS issue tracker was filled with comments on how it didn't really make sense. I don't think TS would have ever gotten strict null if Flow didn't "compete" with it.

Them being separate allows the projects to try stuff the other group disagrees with and prove they are right. I very much like that.

Beyond that, the 2 projects really are VERY different. Again, with strict null and all the pain, it's causing on the TS side. It's not easy to just bring in features of one and merge them to the other. The entire architecture is different (eg: the flow inference). Then there's the pitty shit: I don't know if they're involved with TS, but some very visible Facebook people just can't handle the fact that the entire world doesn't revolve around Unix, as nice as it would be if it did.

Some stuff is sparking some collaboration. Babel getting support for TypeScript syntax for example.

Strict null in TS was before flow public release.
That is not true at all!

Flow was announced November 18, 2014: https://code.facebook.com/posts/1505962329687926/flow-a-new-...

Typescript got --strictNullChecks with Version 2 which was announced July 11, 2016: https://blogs.msdn.microsoft.com/typescript/2016/07/11/annou...

Even if I'm being charitable and look for the date when the PR (https://github.com/Microsoft/TypeScript/pull/7140) was merged, we'd only get April 2016.

> The question is why don’t they collaborate and unify the efforts?

I have really wondered this. I suspect that the two projects had slightly different goals in the beginning, and are now slowly borrowing ideas from each other.

I think the only way they could truly merge is if ECMAScript standardized the subset which they both use and then TS and Flow could be used to introduce experimental proposals kind of like Babel does now.

I completely agree except for the part where it's useful.

In my mind, Flow is dead. The issues are mostly ignored, third-party type definitions are sparse and of varying degrees of bad to completely wrong.

> I find the whole situation very unsatisfying. It is clear - when you actually use it heavily for a big project for a longer period - that a type system on top of Javascript is very difficult to maintain.

Agreed. This is a tough problem and it's a never-ending maintenance battle. This is especially true for an ecosystem that prides itself on making npm packages as small as possible ... they all need typings!

> On the bright side, once you get your code all "type system ready" you really do find bugs - even if it's just a few.

> ... even if it's just a few.

This is exactly the conclusion we came to in our large codebase and we decided to rip it all out. We didn't see the win at all. We ripped it out and didn't notice a single difference in our dev workflow. We also got the benefit of reducing our syntax cognitive load.

> There is too much friction between the language and the type system.

Agreed. An optional type system is a maintenance nightmare. The amount of time it takes to get it right cannot be understated. It wasn't worth it for our large web application and the benefits are so minimal imo.

> I validate an object manually and I still have to do an "any" cast in Flow because Flow does not recognize that my `if` statement secures the type.

Try this instead:

    import { reify } from 'flow-runtime'
    import type { Type } from 'flow-runtime'
    type YourData = { ... }
    const unknownObject: mixed = ...
    const validatedObject: YourTarget = (reify: Type<YourData>).assert(unknownObject)

See https://github.com/codemix/flow-runtime/issues/150 and https://codemix.github.io/flow-runtime/#/docs/type-refinemen...

The `reify` marker from flow-runtime and the accompanying Babel plugin will produce a runtime type object that can validate your data at runtime according to your Flow types.

> I find the whole situation very unsatisfying. It is clear - when you actually use it heavily for a big project for a longer period - that a type system on top of Javascript is very difficult to maintain. LOTS of unsolved cases and issues. You definitely have to adapt and use only the subset of Javascript and the type system that works

This is spot on. I prefer type-driven development. But maintaining these typings is costly. Maintaining the definitions upstream is also difficult. GOing back to my redux / router example. There was one class they were going over again and again. Because it had a number of permutations and didn't meld well with a type system.

I found the TypeScript contributors very responsive on GitHub issues. Maybe I'm just lucky?

I just submitted a bug[0] on Jan 5 and it got fixed on Jan 9.

Another bug[1] from a couple years ago was submitted Aug 4 and fixed Aug 5.

I'm pretty satisfied ;)

[0]: https://github.com/Microsoft/TypeScript/issues/21031

[1]: https://github.com/Microsoft/TypeScript/issues/4155

Also in the flow camp for our project, I originally chose it over typescript because it seemed to fit in the react ecosystem better, but I've found that typescript has way more typings in their type repo than flow, and sometimes I wonder if the grass is greener on the other side.

I don't mind the "types on an untyped language" situation, it reminds me of C (the original). Any project that gets big enough eventually picks up a few `void*`s.

Well, typescript has a full time team complete with a project manager and all.

Flow is more like a side project that is completely getting out of hand. typescript stole all of flow's best ideas and they have way more man-days to apply to problems.

These projects are hardcore. Being able to strap a type system on top of the monstruosity that is JS is very hard. On top of bug catching (this may not even be the major factor for me) it adds invaluable type documentation that remains in sync with the code to the projet; you just can't load everything in your head, models and all.

> Flow is more like a side project that is completely getting out of hand.

Flow is used on all of Facebook's modern internal front-end code, and has a dedicated team maintaining it. They release major bugfixes and new features on an almost weekly cadence.

The "issues" count above is the 3rd party library definitions, which I don't think Facebook involves themselves too much in. The community for TS is larger, so therefore more issues will be found and fixed.

I disagree. I've used both Flow and Typescript for a few major projects. I was able to resolve virtually all of my Typescript issues by googling. Flow on the other hand required many github issues and most of them were ignored or unresolved. In my mind it's a no-brainer, Flow is dead and mostly unmaintained from an open-source point of view. I'm sure the Flow team is great but they only care about one consumer, the Facebook.

They should slap an unmaintained notice in their project and direct people to Typescript and save everyone a whole lot of hassle, including themselves.

That isn't to mention the third-party type definitions are completely lacking on the Flow side.

Flow is dead.

What do you disagree with, exactly? You just said, "I disagree", and then wrote a bunch of unrelated stuff.

Sorry that you had a bad experience. I've been using Flow for more than 2 years now and couldn't be happier.

What does "unmaintained" mean to you? Other than during Christmas, they release almost every single week [1].

[1] https://github.com/facebook/flow/releases