
Flow vs. Typescript - dmnd
http://djcordhose.github.io/flow-vs-typescript/2016_hhjs.html#/
======
greenspot
I like very much the last slide and the author's recommendation. Helpful and
better than the admonitory 'yes you should use typed JS':

\- if your project does not live for long: no

\- if your project is really simple: no

\- if there is a chance you will need to refactor the thing: yes

\- if your system is very important or even crucial for the success of your
company: yes

\- if people enter or leave your team frequently: yes

~~~
Hurtak
> \- if people enter or leave your team frequently: yes

Interesting, I would put that one as a no, since introducing TS to you project
means longer time train new employees. On the other hand it will make sure
their commits break something less often, so not so sure about this one

~~~
cageface
The learning curve on something like TS for people already conversant in JS is
pretty shallow. I think the time invested learning it will pay for itself very
quickly on any non-trival project.

I wish I had something similar for all the Ruby code I write.

~~~
chris_st
You might want to check out rubocop[1]. It does static checking, and we're
pretty happy with it.

1: [https://github.com/bbatsov/rubocop](https://github.com/bbatsov/rubocop)

~~~
RussianCow
Does it actually do static type checking? Because I don't see anything about
types in the documentation. It looks like just a more sophisticated linter,
which is very different from what TypeScript and Flow bring to the table.

~~~
chris_st
Ah, you're right. It's "just" a linter... but a pretty good one.

------
Skinney
The main problem for me, is that Flow doesn't support Windows (yet?). I've
been working solo on a frontend a couple of months now, and the team has just
been extended with a new developer (yay). However, he uses Windows, and so all
my type annotations are worthless. We're making the switch to TypeScript once
2.0 is released (easier to port with strictNullChecks).

~~~
greenspot
Really wondering: who is developing Node/JS on Windows nowadays? Not that I
don't like Windows (I like W10 + the new Ubuntu within efforts a lot), but the
ecosystem around Node is so much tailored around Linux. Even with OSX where we
have an excellent support, there's still some slight friction when deploying
to Ubuntu.

Or is Windows 10 a viable alternative for Node devs?

~~~
skrebbel
> _but the ecosystem around Node is so much tailored around Linux_

I really don't understand why people keep saying this, it's simply not true.
Node works _fantastically_ on Windows. I've yet to come across a library that
won't work on my Windows box (barring obviously platform specific stuff).
Node-gyp works fine too, and many libraries with native code offer Windows
versions.

Especially when comparing to e.g. Ruby or Python, it's a world of difference.
With Ruby you can't even use bundler on Windows and then deploy on Linux.

It seems all the basic fundamental design choices of Node and NPM were made
with portability in mind. I'm frankly quite impressed.

Source: been running teams doing frontend and node for almost 3 years now,
every team had at least one Win dev and at least one OSX dev, every team
deployed to Linux. 0 problems, ever.

~~~
Aldo_MX
> Node works _fantastically_ on Windows.

I beg to differ

1\. npm install gulp

2\. try to delete the node_modules folder

3\. waste time fighting windows' legacy stuff (260 max path length in almost
everything: explorer, cmd, git bash, etc.)

4\. come across rimraf eventually

I wouldn't describe that flow as "fantastically" unless you mean
"fantastically broken".

~~~
Joeri
Not that it helps today, but the upcoming w10 anniversary update is going to
get rid of the 260 char path length limit.

Microsoft is waking up to the fact that developers mostly aren't using
microsoft dev tools anymore. Hence, docker on windows, ubuntu on windows,
redesigned env vars dialog, no more path length limit, nicer command prompt,
etc...

~~~
livus
Finally. But I wish microsoft would've done it sooner. Now a UNIX convert.
Forever a convert. I'm no longer fighting my system to get shit done.

------
msoad
Both differences in this presentation are addressed in TypeScript 2.0

[https://github.com/Microsoft/TypeScript/wiki/Roadmap#20](https://github.com/Microsoft/TypeScript/wiki/Roadmap#20)

~~~
bsimpson
I talked with Lee Byron about the differences and if there's hope for
convergence at React Europe. He said:

\- the biggest difference is nullability (you have to explicitly set
TypeScript to treat all types as non-nullable by default to get behavior
similar to Flow's default).

\- Flow uses nominal typing (similar to functional languages); whereas,
TypeScript uses structural typing (similar to Java). To be honest, I don't
remember the ramifications of this, but I think one was it makes Flow easier
to work with/require less boilerplate. If you set types on your exports, Flow
can infer the stuff in the middle. Flow is also compatible with prototype
chains; whereas, TypeScript only knows about ES2015 classes (unless you
declare types separately in t.ds files).

\- Because TypeScript is a compiler, they can define their own syntax. Flow,
on the other hand, tries to be compatible with pure JavaScript. (You can
define Flow annotations in comments to avoid needing a tool like Babel.) This
means the syntax for certain operations is a bit more verbose in Flow: I think
the nullable operator was one case, where the operator Microsoft chose could
be ambiguous with JavaScript code in Flow, so Facebook chose a different one.

In short, there are inherent architectural differences that make the two
incompatible - there can be edge cases that make a file that works in one not
work in the other. The two teams share notes and try to avoid divergence when
possible, but as the slideshow shows, the projects have different aims, which
can yield conflicting decisions. If Microsoft adds support for the Flow
nullability operator, there ought to be a large subset of shared syntax
between the two, where files that work in one should work in the other, if you
set TypeScript to use Flow's defaults and don't rely on nominal typing.

These are all notes off the top of my head from last week. I haven't used
either tool yet. Please feel free to correct any mischaracterizations.

~~~
itsyogesh
I know I sound a little ignorant, but could you elaborate a little on
nullability. I mean is it the same as checking whether an assignment is null
or not?

P.S. I haven't used either typescript or flow.

~~~
wpietri
The basic notion is that part of the meaning of a type is whether it's allowed
to be null. As developers we have notions of whether some variable is supposed
to ever be null; this is just asking the computer to make sure.

For example, suppose you're building a simple app to remind you to call your
friends on their birthdays. Your fields are name (a string), birthday (a
date), and phone number (a string). Since it doesn't make sense to put
somebody in without a name and birthday, you say those aren't nullable. But
say you want to be able to leave a phone number out, because it's easy enough
to look up their phone number when you want to call. So phone would nullable.

Java, as an example, required everything variable to be typed, but all
references could be null. This meant that far and away the most common error
in Java logs was NullPointerException. It's great to see language features
aimed at reducing that.

------
OmarIsmail
No matter which one you go with if you're project is going to live for any
decent length of time please use one of these. Typed Javascript plugs many
holes in the language and there is a qualitative positive difference in
productivity.

Just go with one of them. Seriously.

------
abritinthebay
The biggest win that flow has - and for me puts it over typescript - is that
it has comment decorator syntax.

This means I can _just write JavaScript_ and add comments for types. No
transplier step, no messing around in a different but similar language, no
additional complexity, just easy.

It's inferred types are a much stronger system imo too - gets out of a
developers way more.

Typescript is great, but I really do prefer Flow in every metric.

~~~
smt88
> _no messing around in a different but similar language_

TypeScript would be a disaster if it subtly changed the semantics of
JavaScript. It doesn't, though. It's a superset, so it's really not a
"different but similar" language. It's the same language with more features,
and the compiler is a great guide to using those features.

~~~
tkubacki
what if further JS will intersect with TS syntax ? IMO Typescript is "no go".
We need clean break with transpile step (eg. Dart) or annotations.

~~~
smt88
> _what if further JS will intersect with TS syntax_

A core value of TypeScript is to support the latest ES20xx standard. The
TypeScript team pays attention to JavaScript proposals. In the unlikely event
that JavaScript got a type system, it would almost definitely be either
TypeScript or Flow. If it wasn't, or if ES standards overlapped with TS
syntax, then TS would remove that syntax.

Also, if you don't like the next version of TS, you can just use the old
version to transpile your code and then stop using it. Switching to TS is an
easily reversible decision, whether it's 1 day or 1 year later.

> _We need clean break with transpile step (eg. Dart) or annotations._

You can already have this with Scala.js or any of the other languages that
compile to JS. TypeScript is one option among many.

The appeal of TypeScript is that it fixes some things about JavaScript rather
than throwing the language away. That's useful because it allows teams to
transition from one to the other gradually. Facebook had to do the same thing
with PHP, so they created Hack.

~~~
tkubacki
"then TS would remove that syntax."

So there is no hard promise of TS backward compatibility ?

Sorry but whole TS looks like another EEE - MS will/can argue on some further
JS changes for/against based on existing TS codebase. I hope I'm wrong here
though.

~~~
oblio
You want to have your cake and eat it, too. You've just argued for both
viewpoints (TS is bad because it does X and because it doesn't do X).

Just be honest and recognize that you dislike Typescript and/or Microsoft.
Nothing to be ashamed of, many decisions in tech are based on feelings as much
as on cold, calculated decisions.

~~~
tkubacki
What? I want TS to be different lang transpiled to JS or be annotation to JS
but it is: Embrace and extend existing Standard (superset) and when everyone
will write TS it will come to Extinguish step. (I like C# and don't like
Windows my like not like to MS tech is 50%)

------
tinza123
TypeScript 2.0 added control-flow based analysis, therefore cases like the one
in slide 12 will be cached with the `strictNullChecks` flag.

------
chvid
I am the only one who is happy to code without static typing? Enjoying fast
compilation, small, fast editors, flexibility.

I don't really make stuff like marry(a, b) and then call it with a banana and
an apple by accident. Sure I make plenty of mistakes when I am coding but only
very few could have been caught by a static type check.

Take one of the examples in the slides:

    
    
       let obj: string;
       obj = 'yo';
       // Error: Type 'number' is not assignable to type 'string'.
       obj = 10;
    

I simply don't write code like that. The crucial difference is that I would
pick a variable name that made it obvious what goes in it:

    
    
       let text = 'yo';
       // This line here - I would not in practice write as 10 obviously does not belong in text:
       text = 10;
    

(similarly I would never use the variable name 'what')

~~~
adamors
How big are the projects you are working on though? For instance I work an a 2
year old Angular project and static typing is something we are trying to
introduce because the codebase is large and challenging to work with, mostly
because Javascript. There's only so much you can do with best practices and
code organisation.

~~~
chvid
I work on / have worked on fairly big projects. Plenty of them have been "a
challenge to work with". Always because of the code that had been written (+
other things). Never because of the language.

For me the trick to big projects is strong modularisation and well-defined
interfaces which you can do regardless if you have static type checks or not.

~~~
chvid
Plus. I think that there is a bit of developer-psychology-101 here.

Most developers would rather go: This project sucks. This shitty language has
not got a proper type system. Let's build a compiler/type-checker/use-this-
cool-alpha-from-bingo-banana-I-found-last-night.

Rather than: This project sucks. I cannot believe how much bad, disorganised
code we have written. Let's sit down and look at our mess to see if we can
improve the way we write code, work together and in general develop way we
make software.

~~~
plgs
I don't see these as mutually exclusive. Introducing a compiler/type-checker
can be (depending on your situation) a very concrete way of improving the way
code is written.

~~~
chvid
They are not. But the pscyhology is that people will much rather talk about
introducing a new tool rather than what they have done wrong.

------
runn1ng
From my experience - Flow is still very "unstable" and in heavy development. I
haven't tried TypeScript at all, so I cannot compare that.

It's absolutely true that Flow team is merging all pull good requests, fixing
issues (the backlog is big - 500 issues - but TypeScript has 1000, so it's not
incomparable) and the system is made dramatically better every release.

But there are still rough edges, especially when working with ES6 modules and
import/requires/etc.

Again, I don't know how TypeScript compares, I learned Flow and am just using
that.

~~~
whatever_dude
The good thing TypeScript has going for it is tooling. It's really solid. IMO,
VSC is a pleasure, and the tools (tsc, tslint, etc) are extremely stable.
Things don't break.

The GitHub community is going really fast, and I love reading some of the PRs,
but it's hard for me to compare in that sense.

------
gear54rus
So today is typed JS day?
[https://i.imgur.com/XAEeEFm.png](https://i.imgur.com/XAEeEFm.png)

Guess it's time for the question then... I haven't dived into this whole types
thing yet so could someone provide a TLDR about either Flow or TS being
opinionated and their impact on an established toolchain?

I have no intention of changing half of my tooling just to be compatible with
what fb thought would be a good idea, and even less so for ms. A build step is
required, I take it, but that's not a problem. Would I be able to use old libs
and build tools? Are there properly working code formatters for both? What
about editor support (Sublime)?

I also understood that TS is a superset of ES6, what is Flow's relationship
with ES6+?

~~~
smt88
> _Flow or TS being opinionated_

Neither is opinionated. They have some pretty uncontroversial (similar to
other popular languages) typing on top of JS, and it's all opt-in. If there's
something you don't like, you don't have to use it.

> _and their impact on an established toolchain?_

I don't know about Flow, but TypeScript is very easy to integrate into an
existing chain. If you're using something like Gulp, there is a pure JS
library that you can call to transpile your TS into JS. If you use Babel, you
can simply insert the TS->JS transpilation before you call Babel.

TypeScript has an executable called tsc that you can use to transpile your TS
whenever the file is changed. You can use that, and then your tool chain
doesn't even have to change at all. (Automatic TypeScript transpilation is
built into WebStorm and easy to add to VS Code.)

> _I have no intention of changing half of my tooling just to be compatible
> with what fb thought would be a good idea, and even less so for ms._

In my limited experience, TS is much more polished than Flow is. The tooling
is mature, debugging works well, and the language is rapidly improved. It's
not just MS using it -- Google also uses it, and some other larger companies.

> _A build step is required, I take it, but that 's not a problem. Would I be
> able to use old libs and build tools?_

Anything (and I mean _anything_ ) you do with JS, you can also do with TS.
It's a superset of JS and compiles to readable, idiomatic JS.

> _Are there properly working code formatters for both?_

WebStorm has mature formatting for TS, but there's also tslint if you want
some additional error-checking. WebStorm has first-class support for TS,
including integration with tslint.

> _What about editor support (Sublime)?_

No idea about Sublime, but WebStorm support is absolutely fantastic. Excellent
debugging, hints, linting, and completion. VS Code is great, but it lacks some
of the more niche-y features of the IntelliJ platform. Some people might not
care, and VS Code will do everything they want.

------
cabalamat
This would be a good deal less irritating if it was written as an essay and
not a slideshow.

~~~
untog
You could always rewrite it yourself.

Not every submission to HN was created as or intended for a Hacker News
audience. The author wasn't under any obligation to publish their slides,
personally I'm glad they did.

~~~
cabalamat
> Not every submission to HN was created as or intended for a Hacker News
> audience

That's a good point.

------
robinricard
Both systems are really great, however, when adding typechecking into an
existing codebase, flow does offer more flexibility thanks to weak checking
and annotation comments. You can really progressively add typechecking by just
dropping the tool in the codebase. Also, if you subscribe to Facebook's
tooling (Nuclide especially), you will end up with great tools (jump to def,
integrated checking, ...). However if you just start the project and you use
VSCode, TS seems to be a strongest choice. Depends on what you do, but both
tools are great, whatever you choose, typechecking is worth in javascript if
you need more reliability and maintainability.

~~~
hoodunit
I actually found the opposite was true in our project - TypeScript was easier
to add into the code than Flow. The biggest reason for this was that Flow
demands null/undefined checking and null was used extensively throughout this
code base. With TypeScript, on the other hand, the changes to make it work
initially amounted to sprinkling a few "any" notations and making some
explicit object interfaces at various points.

~~~
shados
Flow supports nullable types just fine, and flow in weak mode doesn't mandate
any annotation whatsoever.

------
solomatov
The best things about flow which typescript doesn't have is sound typesystem.
I hope typescript will adopt it at some point in time.

~~~
hoodunit
One area in which Flow may be "technically" sound but it feels illogical is
how in how it infers certain types. TypeScript requires that a variable has
one type that doesn't change, but Flow will infer multiple types for a
variable at different points in the code depending on how it is used. Also
because Flow infers types based on how they are used, there are some
interesting situations where you would expect the type checker to complain but
it doesn't. E.g. if you have an object with a field that is never used, Flow
won't complain about the field even if it is not defined in the type of the
object. Overall I feel like TypeScript enforces logical, opinionated defaults,
while Flow is happier to go with the illogical structure of your own usage
(while enforcing opinionated defaults in other areas like null-checking).

~~~
alectic
Jeff here (I work on Flow).

I talked a bit about why we infer unions in this way in my ReactEU talk
earlier this week
([https://www.youtube.com/watch?v=VEaDsKyDxkY](https://www.youtube.com/watch?v=VEaDsKyDxkY)).

Ultimately it boils down to the notion that inference is about understanding
the type, and annotations are about expressing it.

If you write a type annotation for a variable, then Flow will of course not
infer anything more or less than your annotation. If, however, you use the
variable as multiple types (but do so in a way that is clearly safe), Flow
infers the union so that it doesn't give you errors for code that is clearly
ok.

I think the example from the talk was something like:

    
    
      var name = "Jeff";
      name = name.toUpperCase(); // safe
      if (loggedOut) {
        name = null; // safe
      }
      var firstInitial = name ? name[0] : null; // safe
    

The above code has no errors in it, and because flow infers `name` as a type
`null | string`, Flow is able to verify its safety and thus doesn't error.

OTOH, if we use an annotation to _express_ the type of `name` as intended as
only `string`, then we would get an error on the null assignment:

thing like:

    
    
      var name: string = "Jeff";
      name = name.toUpperCase();
      if (loggedOut) {
        name = null; // Error!
      }
      var firstInitial = name ? name[0] : null;
    

So in summary: Inference is the means by which Flow understands, annotations
are the means by which you express to Flow your intentions.

------
Matthias247
Regarding the first class definition with TS (sayer):

You can shorten the it by declaring the public variable within the
constructor: constructor(public this.what: string) {}. Thereby you can
eliminate the property declaration as well as the assignment inside the
constructor.

And regarding the non-nullable example for Typescript: I think there is an
non-implicit-returns option or something similar for the compiler which would
have warned you that the function is incomplete. Of course it wouldn't help if
you manually return null/undefined (which is valid).

------
whatever_dude
Good presentation. But two caveats:

First, the slides about lack of non-nullable types in TypeScript are
incorrect, if you count the beta ("next") versions. It's already part of 2.0
[1] which should be out soon [2]. He says "there is hope" but it's more than
hope, it's a certainty. (the date of the presentation is not clear, but seems
outdated to me)

Second, there's a lot of other features that are left out. Union types,
flexible interfaces, etc. They're not on par between the two languages, but
many of those are almost as helpful as types, just more specific, so they're
important if one is trying to draw a comparison.

[1]
[https://github.com/Microsoft/TypeScript/wiki/Roadmap#20](https://github.com/Microsoft/TypeScript/wiki/Roadmap#20)

[2]
[https://github.com/Microsoft/TypeScript/milestones](https://github.com/Microsoft/TypeScript/milestones)

------
michaelwww
Slide 12 is incorrect. TypeScript does catch this with a "not all control
paths return a value"

------
fridek
I think the biggest loser in this comparison is Closure Compiler, which is
around for years with all those features. It's also still active with
development on understanding and transpiling ES6 and even TypeScript from what
I've heard [1]. There also made a good move recently, enabling ES6 modules
packages instead of its own goog.provide/goog.require.

Yet, the available toolchain for it is years behind others. If you wonder how
you should have any live reload development with it, you can either rely on
community plugins like grunt-closure-compiler [2] or hope plovr[3] is finally
resurrected back to a state where it's usable. This all sounds fine until you
think about any unit testing. The only karma runner[4] for closure is simply
broken and unmaintained. Even worse, most of npm packages you might want to
compile with your code will output thousands of errors because there is no
clear way to whitelist code as "not my code leave it alone". I can just hope
one day Google will publish a yeoman generator with all those things solved
and get it back in the game.

[1] [https://groups.google.com/forum/#!msg/closure-compiler-
discu...](https://groups.google.com/forum/#!msg/closure-compiler-
discuss/5EVAw6oO2BI/LI9ptKLnCYoJ)

[2] [https://github.com/gmarty/grunt-closure-
compiler](https://github.com/gmarty/grunt-closure-compiler)

[3] [https://github.com/bolinfest/plovr](https://github.com/bolinfest/plovr)

[4] [https://github.com/karma-runner/karma-closure](https://github.com/karma-
runner/karma-closure)

------
CuriousSkeptic
One aspect to consider before jumping into TS or Flow. As is the nature of any
type system they rule out some programs that are perfectly fine.

A workaround for this is to infer, or explicitly annotate, things to be
dynamically typed. And/or helping the typer by casting to known types it
failed to recognize. And it will work fine, after all this is precisely what
you do with untyped ES (in your head).

This workaround was to strong of a code smell to just let things be like that
though. So I've found myself spending time inventing ways to refactor code, or
alter type definitions, to get proper typing instead. This can eat up time
better spent implementing features.

Not everyone will have this problem, but if you're anything like me, do
consider it before adopting these.

As a less intrusive option, consider using eslint with Babel and reference
checking for modules. Not in any way a complete type-system, but might be just
enough if you're allready comfortable with ES as it is.

~~~
lobo_tuerto
Do you have a specific (and simple, if possible) example at hand?

~~~
CuriousSkeptic
Redux perhaps. Spent some time inventing a way to pass event types to
reducers.

Turns out I reinvented redux-act in the end ;)

------
avodonosov
Where I saw the same nullable / non-nullable values: Kotlin.

Bidning animals = cats is problematic only if the collection is mutable.
Forbidding that is too limiting when you work with immutable collections (even
it that's an Array - if you are not going to mutate it).

------
Hurtak
I heard somewhere, that TS class syntax diverged somewhat from the spec. Can
anybody who has insight into the TS tell me what the situation is?

------
DJCordhose
What currently is in TypeScript:
[https://github.com/Microsoft/TypeScript/wiki/What's-new-
in-T...](https://github.com/Microsoft/TypeScript/wiki/What's-new-in-
TypeScript)

------
karmakaze
Flow is more strict than TypeScript as demonstrated by the slides. As such why
not use it as a static checker for TypeScript? I don't see it so much as a vs.
situation. Unless you mean to use the unsafe area in what is valid TypeScript
and invalid Flow.

------
DJCordhose
What TypeScript 2.0 promises:
[https://www.infoq.com/news/2016/04/typescript-2-preview](https://www.infoq.com/news/2016/04/typescript-2-preview)

------
moomin
If you really want good types with your JS, there's always Purescript. (I'm
half serious.)

------
bkad
Love the use of Zenburn in the syntax highlighting :)

