122 comments

[ 3.5 ms ] story [ 230 ms ] thread
My favorite: the new `object` type. Non-nullable and cannot refer to primitives.
The new `react-native` jsx target is also a good step in the right direction of creating smooth React Native projects in TS. I can't wait for it to be a seamless dev experience, but now the ball's in RN's court. [1]

(Context: using TS in a RN project is currently a bit disjointed because of its closed dev bundling workflow. You need a separate build task running concurrently to feed JS files to the main watch/build task.)

[1] https://github.com/facebook/react-native/pull/11932

Non-nullable

This is incorrect, as is the announcement. The following is valid.

  class Bar{}
  let foo:object = new Bar()
  foo = null
  foo = undefined
edit:

For the people mentioning, --strictNullChecks. That applies to all types not just object. For example, "let x:string = null" would also be an error. That option applies to any type that is not of type Any/null/undefined, and has been in place since 2.0. In that way, "object" is non-nullable under strictNullChecks just as every other type is.

No, object is not a nullable type.

For your code to work, you'd need to run it with strictNullChecks disabled. That's probably what you're doing, since it's the default.

Without `--strictNullChecks`, both `undefined` and `null` are in the domain of all types.
since it's the default.

It's not the default for the command line compiler. Also, all types (except Any/null/undefined) are non-nullable under that option, so that's not what makes object special (it's the no primitive types that is important).

  >tsc test.ts
  >tsc test.ts --strictNullChecks
  >  test.ts(3,1): error TS2322: Type 'null' is not assignable to type 'object'.
> you'd need to run it with strictNullChecks disabled. That's probably what you're doing, since it's the default

I think you misinterpreted my reply. I meant the default is off. That's what your code shows.

I did, sorry about that.
Thanks for catching - I've updated the blog post. I tend to just use `strictNullChecks` by default, as it's typically the best option for any new code. :)
Can you show a few examples of where this is useful?
You can read the proposal and discussion around the feature on the github suggestion page for this feature.

The initial suggestion was made because there are certain functions in JavaScript that expect a non-primitive type in order to function. Such as Object.create, Object.getPrototypeOf, etc. Previous to this there was no way to model the functions with type safety, such that a developer would be prevented from accidentally sending a primitive value into those functions. This is because Typescript doesn't have the ability to say "Any type except X, Y and Z". So a new type was needed for this.

https://github.com/Microsoft/TypeScript/issues/1809

Thanks. Sounds useful especially for library authors.
Object type, better index access, and the quick fixes are all great additions. Awesome job TS team, keep it coming!
Relaxing index-signature access is definitely great as it will make writing code easier. Dynamic properties can lead you to hairy code but it's hard to ignore the reality that it's used everywhere.

For example, no more awkward `e["code"]` where `e.code` is just as valid.

Speaking of tooling -- has anyone had a good experience with Typescript in IntelliJ/Webstorm? It does a fantastic job figuring out ES6 code but seems to totally choke on Typescript. I'd like to avoid switching to Visual Studio.
That's odd. I work in a 100% typescript shop and about half the devs use intellij and webstorm full time without much trouble.

Jump to definition/auto import/implement interface/etc all work.

I'll second that. I use an IDE from the Intellij family and things work fine.
Make sure you turn on the native TypeScript Language Service feature, otherwise you'll be getting your IDE's parser, which is always behind the standard and doesn't work very well:

> Select the Use TypeScript Service check box to get native support from the TypeScript Language Service according to the up-to-date specifications. In this case syntax and error highlighting is performed based on the annotations retrieved from the TypeScript Language Service while code completion lists contain both suggestions from the TypeScript Language Service and suggestions calculated by IntelliJ IDEA itself.

https://www.jetbrains.com/help/idea/2016.2/typescript-suppor...

Well that solved some problems (e.g. importing from react-router/lib/*) but autocomplete for TSX is non-functional. Still pretty frustrating considering ES6 works out of the box.
I could be doing things wrong but in my exp, Webstorm's autocomplete is non-existent for anything that you import
Strange, it seems to work fine for me. Find usages on the other hand is a totally random mess.
I have the same issue for some of the libraries. I'm just starting with TS so it can be user error. However, I found that you can download the typings in the IDE in Settings/Javascripts/Libraries and download... This is tedious to have to do this though. Note: doing this works with normal JS as well which is pretty cool.
I've been working VS Code with TypeScript regularly for over a year now. It sounds like you want to stay in Intellij, but the language services experience in VS Code is top notch for TypeScript.
IntelliJ Ultimate user here, writing and refactoring TS works quite well. There are some minor issues (e.g. sometimes it doesn't show the usual "this method is overridden in a child class" indicator), and refactoring likes to randomly modify somearray['foo'] when renaming a someclass.foo property, but I can live with that.
How is Flow looking in webstorm? As good as their typescript support?
I haven't tried Flow, so I can't say.
I've used both extensively in IntelliJ IDEA Ultimate. It's slightly harder to setup than TS, and it feels less mature - but it's very hard to explain why with concrete examples.

I did have to turn off code completion based on flow, because it slowed down the IDE noticeable (they do warn of this next to the setting...), but I hope that support will improve in the next versions, as flow gets more mature.

The inspections, autocomplete, and auto-import suggestions work great for me, but it doesn't seem to have that "show type on hover" functionality (not even Ctrl+hover, or quick documentation show it), that VSCode and even the online Monaco editor on http://www.typescriptlang.org/play/ have.
Pressing the keyboard shortcut for the "expression type" command is not that cumbersome though (default: ctrl + shift + p).
That doesn't seem to show the same information as VSCode though. If you go to https://goo.gl/zteCbj and hover over the `x`, it will show type A. If you hover over `y` it will show either AB or B|null, depending on whether you have strictNullChecks enabled. IntelliJ also doesn't show any information for type aliases.
For passersby who were confused like I was: IntelliJ Community Edition has absolutely no support for Javascript or Typescript, which is not noted clearly in the help docs. You apparently need Ultimate Edition to get it.

I was real excited that I could finally use the same IDE for front-end and back-end too... :/

The price gets lower each year for the first few years you renew your license.

My company pays for my license but I think it's hella worth it and I'd pay it on my own if I had to.

I avoid VS like the plague and I've never really felt at home in an IDE until I started using IntelliJ.

It's the only thing that was able to get me off of Notepad++

I also avoid VS, but VSCode is nothing at all like its big brother. It's actually very quick and lean.

If you're interested in TypeScript at all, the two were made for each other. I'd suggest giving it a try.

Just note it's closer to a text editor with IDE functionality, rather than a full-blown IDE itself.

I can pretty much get that and more with Notepad++ or Sublime, though. I've moved back to vim for simple text editing, N++ for casual writing and organizing my thoughts. Is there any specific feature that makes it better than other editors in your book?
Apart from Intellisense completion, a full featured integrated debugger, version control integration wich supports line wise staging, a diff viewer, a fast integrated terminal that even gets link detection in the next release, proper variable renaming and a working "Go to Definition" that is even implemented in most of the third party language plugins?

No. Pretty much the same as Notepad++.

IntelliJ has all of those things. I'm not sure you understood my question. I use Webstorm daily, I'm using it this very moment. I was asking about VSCode and where it falls between IntelliJ and N++.
I also use WebStorm. But VScode is lightweight, starts up in two seconds and typescript support is always up2date with the latest typescript release. Changing user/language preferences in VSCode is a breeze as you simple open and edit the settings files with rich language support and intellisense. WebStorm requires you to open that horrible application modal Settings dialog. VSCode is also highly responsive compared to WebStorm which tends to lag a bit. I also like the quick info and peek features of visual studio code. However, there are folks who find this distracting.

WebStorm beats VSCode hands down in refactoring though.

Yeah Webstorm's got a killer refactoring engine.

When I first began using it the lag made it unusable. I'm talking up to 2000ms delay for visual feedback on my typing. Somehow that resolved itself over time though, and with my newer rig it's actually pretty damn snappy. It only takes about 15-20 seconds to spin up a virtual machine and launch Webstorm. I can't imagine how quick VSCode might be for me. I'll have to try it out tonight, everyone here has convinced me it's worth checking out.

I understood the question – and that IntelliJ has all of those things is exactly the point I was trying to make.

You get most of the features from a heavyweight IDE, but they managed to get the architecture incredibly lightweight so you can use it as a "daily driver" editor as well.

It is snappy enough to quickly edit some configuration or Markdown files (with live preview and clickable links), it has text based configuration files, its easy to write plugins with a couple of lines of code – and all sorts of other things that previously could only be found on the "editor-side" of the spectrum (export VISUAL="code -w", anyone?).

Unique selling points are quite hard to find, most things where invented somewhere else. Its more the combination of things and walking the thin line between the text editor and IDE worlds.

Oh ok, I just didn't understand your answer. My apologies!
VSCode is a lightweight IDE, despite them branding it as an editor, it understands project structure, has integrated debugging, task runners, GIT integration.

Honestly if I could get TFS integration on the level of GIT (for work, although ideally we would migrate to GIT) I would dump VS - it's bloated, when stuff fails you have no clue why or hope of fixing it, VSCode mostly wraps CLI tools so if the default integration fails you can work your way through it, unlike fucking TFS magic VS integrated tracking failing or whatever.

VS is still the only choice for .NET proper, but for .NET Core VSCode is usable enough and improving.

TS integration is the best I've seen, they are the first to support new TS features

> I also avoid VS, but VSCode is nothing at all like its big brother. It's actually very quick and lean.

VSCode is an Electron app, that means that it is written in Javascript and HTML5. Electron apps are notoriously resource intensive even though their UI is typically responsive. Watch your CPU usage spike and battery life plummet as you use Electron apps.

Even the Slack messaging client (another Electron app) can spike a CPU under certain circumstances. And that is a simple messaging client that doesn't have to parse and markup code like an IDE does.

VS Code is like Sublime Text. Nothing like VS or Eclipse.
Like other replies said, VS Code is nothing like VS.

I've been a dedicated Sublime Text user for years (wary of IDEs like you) but VS code kicks ST2/3's butt for Typescript development.

Thanks, I'll have to give it a shot!
It's a bit of an investment if you're still a student, but if you're working full time as a programmer, the JetBrains IDEs are the highest bang for your buck.

Beyond the basic functionality working, the paid versions have a lot of cross-langauge support (PyCharm gets a huge chunk of the JetStorm functionality) which means that autocomplete "just works".

Like when I'm writing Angular templates, it looks up my custom directives and provides autocomplete on that. It is able to give autocomplete inside Angular expressions (down to looking up the controller and providing type information if you're using Typescript) inside my Django templates.

It's a lot of fuzzy searching but they have very good heuristics.

I think it would be near-impossible to get this cross-language support in Atom/Emacs, if only because it requires the I in IDE. Totally worth it.

> It's a bit of an investment if you're still a student

They have free licenses for students that includes all their products and a discount when you graduate. If you're making money off it, the license cost for intellij or just webstorm is pretty cheap.

https://www.jetbrains.com/student/

>I was real excited that I could finally use the same IDE for front-end and back-end too... :/

And that editor has the absolute best VIM keybinding implementation of any popular IDE outside real VIM / NeoVIM. If you haven't looked yet, this is what finally got me out of the terminal for coding: https://plugins.jetbrains.com/idea/plugin/164-ideavim

My proposition is out of the box but maybe get a chance to VSCode?
In my team we used to be splitted between sublime/webstorm/atom, now we all are pretty happy with VS Code for typescript and javascript.
Moving a team of ~20 engineers from IJ to VSCode for a single technology is a nonstarter. IJ is still the preferred IDE for the backend and works perfect for everything we've used that's not Typescript.
Why do you want turn avoid Visual Studio out of curiosity? It's pretty great now.
I was about to say "Visual Studio doesn't work in Linux," but apparently it (or at least Visual Studio Code) actually does now. Living in the future is weird.
When did VSCode not work for linux???? I'm confused...
FYI VSCode has always been an electron app, and thus always worked on all platforms.

Visual Studio on the other hand is a gigantic IDE that only runs on Windows.

Team's standardized on IntelliJ so everyone already has Ultimate. It works great for everything not-Typescript.
Crumbles from the design-table. Oh look, a new object type. I'm not even sure this is an improvement to straight JS any more, it just fails in more exotic ways from pretending to be something it isn't. Once the choice is made to compile to JS, there are plenty of real languages to choose from.
I don't think you're familiar with what TypeScript is trying to achieve. It's not supposed to be another language entirely, but a standards-compatible type-safe version.
(comment deleted)
I know this probably comes up each typescript thread, but I still cannot figure out why I should use TS instead of flow + es6, and maintaining the typing definitions always discourages me as it's one more thing that needs to be kept up to date. Am I working on old information here?
Why would flow + es6 be better?
Avoid vendor locking. Someday in near future if you don't like flow anymore, you can just strip all type annotations with Babel and move on. You are not risking ending up like coffeescript.
Also, you can progressively opt in to add typing information, while still getting most of the benefits without.
The same can be done with TypeScript. Type inference has been added to it in 2015.
TypeScript type inference is minimal though and doesn't go very far. It falls back to "any" very quickly (and if you use the noImplicitAny option, then you have to type almost everything).

It does a decent enough job at return types, but not a whole lot beyond that.

Do you have a use case where something would be correctly inferred in Flow but not in TS?
The classic example is:

  function double(x) {
    return x * 2;
  }
  const result = double("foo");
Which passes in TS, but fails in Flow. In TS, the 'x' parameter to the double function is inferred as Any.
TypeScript compiles to JS in a straightforward manner as well. If you wanted to move away from TS, you could simply have the TS compiler compile to ES6 and you're done.
But that'd still be transpiled code, right? After getting rid of flow it will be exactly same minus the type annotations. Same cannot be said about typescript considering various language features and syntactic sugar TS offers. Will it run? Yes. Will it feel that it was written by me? That depends.
With target esnext, it produces almost the same output with some spacing differences. Sans the annotations obviously.
Your equivalence with transpiling coffeescript is false. TS doesn't really have "syntactic sugars". Just about everything in it(less the types of course) is pretty far along in the ES adoption process. There are a couple exceptions like decorators that are called out in a very visible manner.

If you target ES6 your code may look identical. Even much of the ES5 down leveling produced code that looks like a person wrote it.

I converted a 10k line coffeescript project(with async/await !) to JS and then TypeScript. The similarities are so far apart they might as well be in different dimensions. But, if you don't want to take a rando posters word for it, it's pretty easy to make a little sample project and see if the output is to your liking.

> Same cannot be said about typescript considering various language features and syntactic sugar TS offers

I think you're vastly misinterpreting what TS is.

It's not anything like CoffeeScript. It's JS plus types and a few other features like Interfaces or advanced ECMAScript features when targetting older versions of the standard.

If you strip away types by exporting to your ECMAScript target of choice, you'll get real JavaScript with the same style as it was written in TypeScript.

It's exactly the same thing you'd get with Flow in that sense. The only additional code you'd get would be for polyfills, but a) those are minimal and b) those will only appear if you export to an older ECMAScript version than the one you wrote it in.

There is no vendor lock.

there are a few minor things like enums and decorators that will need to be compiled because they're not standard and are not just types either (well, const enums are i think?, but the rest are not?).

That's about it though.

That's an objectively incorrect assertion if you're applying that to TypeScript.

The same can be done to it that would be done to Flow: you can just either strip types manually, or just do a single export to your ECMAScripttarget of choice. It'll be native JavaScript. Even the little shims/polyfills it does (to support older ECMAScript versions if you wish to export to it) are optional and can be disabled.

TypeScript has `--target ESNext` this will strip out any TypeScript-specific type annotations, and leave you with standard-track-only JS code that looks identical to your input (modulo type annotations).
> Avoid vendor locking.

It's open source.

> you can just strip all type annotations with Babel and move on.

Are you implying that this isn't possible with TypeScript?

One reason flow might be considered "better" (context is key) is that it plays well with the babel ecosystem, letting one pick and choose their language features.
Typescript and Babel play well together, too.
Yeah, I personally don't mess around with Babel but I imagine you could just take TypeScript's ES6 output and feed it through babel in your gulp/webpack pipeline.
Some people were doing that before TS got async/await compilation directly to ES5 (in TS 2.1). Right now, having Babel in the TS pipeline is not that useful anymore.
It's very useful if you want to use native APIs that arrived with es6: Promise, Map etc. TypeScript doesn't shim those
I've had some major headaches getting TypeScript to work with Babel and Webpack 2. The main reason I had to use Babel was because I wanted to use Webpack 2's tree shaking feature. Do you know if it's possible to use just TypeScript and Webpack without Babel, and still take advantage of tree shaking?

Honestly this is the main thing keeping me from using TypeScript. I've spent hours, maybe days trying to deal with the mess of Babel/webpack/TS combined with ES6 modules (necessary for tree shaking).

Another problem I ran into was using various packages that weren't typed, but I suppose I can solve that by 'allowing' implicitAny.

I'd really love some advice on this because I want to use TypeScript. It's just been a major headache so far because things are complicated enough with all the other moving parts (Babel presets, import vs require, better but still not well documented Webpack 2, etc.).

«Another problem I ran into was using various packages that weren't typed, but I suppose I can solve that by 'allowing' implicitAny.»

You can keep noImplicitAny and any-type just specific packages that can't/won't be typed. The declaration is now as simple as:

    declare module 'path/to/module-name'
Typescript will any type modules that you declare that way. You can also use star (*) and star-star wildcards in the module name.
Oh, that's great! Is that a recent change? I remember circumvrenting my issues with 'declare module' but it was more involved than just one line.
Yes, simpler module declaration is relatively recent to Typescript having arrived in Typescript 2.0 (released in September).
Yeah, that's what I use with Webpack. It's just one more rule on Webpack config, so no reason not to do it. There's many things that are out of scope of TS that are better handled by Babel (like embedding corejs methods based on target browser versions).
If you're using Webpack is it possible to gradually opt files into TS type checking _without_ having to rename them, since you can specify which filename patterns loaders apply to?
It might be worth checking ts-loader or awesome-typescript-loader. I'm not sure how it detects js vs ts in those pipelines. TypeScript can also "compile" JS to check for syntax and other errors, so it may still be extension based. An interesting scenario though.
I believe you might be able to with --allowJs, but to be quite honest I haven't done so. All my projects were TypeScript-based from the start, even if sometimes I end up using JS dependencies.
Picking and choosing language features via babel plugins (many of which will never become part of JavaScript) is an anti-feature. You essentially are creating your own language that only you understand.
The parser features are fixed. The plugins enable/disable them, but they're already "there", just toggled. As far as I know at this point the parser is not pluggable. Babel is a playground for the official TC39 proposals so it might get stuff a little early, but that's about it.

Where the plugins shine is when compiling those (part of the standard) features to something interesting for production. Better inlining, adding debugging and instrumentation, compiling away certain things, optimizing your views for performance, etc.

All things that don't change the language whatsoever, but can improve your debugging or production experience.

That can be done in TS world (and is quite common) by targeting ES6 and piping the result in Babel though. It's just annoying.

You do have things like Prettier not being compatible with TS because different parsers, though.

We don't support custom syntax that isn't already a proposal (meaning it has potential to be in JS), and we also encourage using presets like https://github.com/babel/babel-preset-env instead of providing your own configuration of plugins unless you are more of a power user.

It's our intention as a tool to align with TC39 and transition users to using native JS when it's supported

You support at least 2 syntaxes (JSX and Flow) that AFAIK don't have a proposal to be part of JS.
- You are writing javascript, not typescript.

- When typescript came out, I was an early adopter, and a lot of it's touted benefits were the class-like syntax and constructors to make it more palatable to enterprise shops (not for me, but it was easier to sell to higher ups), this is mostly a moot point now.

- flow can be attached to any codebase as the codebase stands easily. It is, I have found, difficult to bring TS into an existing project.

- flow fits nicely into existing popular js tooling, mainly babel and react.

- no risk of vendor lock in. Maybe TS compiles to pure 100% syntactically correct javascript today, maybe it doesn't in the future. It isn't javascript, so I won't know.

At the risk of probably repeating myself, allow me to give my $0.02:

> - You are writing javascript, not typescript.

Flow's and TypeScript's distance to JS world are the same, and are very similar in most cases. If you want to add type to one, it's the same as in the other. The only difference here is the file extension, since TS tends to like .ts/.tsx.

> - When typescript came out, I was an early adopter, and a lot of it's touted benefits were the class-like syntax and constructors to make it more palatable to enterprise shops (not for me, but it was easier to sell to higher ups), this is mostly a moot point now.

True, although IMO the greatest feature of TS is making your code stronger, not compiling things that are already part of some ECMAScript version.

>- flow can be attached to any codebase as the codebase stands easily. It is, I have found, difficult to bring TS into an existing project.

True, with TS it's more of a lateral move rather than drops here and there.

>- flow fits nicely into existing popular js tooling, mainly babel and react.

TS works just as well; better, IMO, because dev tools (editors, linters) have better TS support in my experience. Writing React in JS to me makes me feel like I'm using Notepad since there's so much TS helps me with that is lost when using a purely dynamic language.

>- no risk of vendor lock in. Maybe TS compiles to pure 100% syntactically correct javascript today, maybe it doesn't in the future. It isn't javascript, so I won't know.

It does compile to pure JS so ejecting TS is easy; it's trying to follow future standards and proposed changes, not create something different; the project is open source. There is no vendor lock in.

There's a few subtle things here. Flow does support annotating types with comments, and can type check React's flowtypes, so you actually can get a fair bit without a compiler at all. In practice, no one does that, so you're still right, but it's worth nothing.

And it's worth noting that TypeScript having its own parser vs the rest of the world using Babel is a pain in the rear. See the time it took for ESLint (having to us TSLint in the meantime), now Prettier, having to use TypeScript with an ES6 target and piping the output in Babel to get proper plugin support, the difference between webpack's resolution mechanism and the one used by TypeScript in tools (an issue Flow also shares), and so on.

Some features like enums (omg, TS enums die die die) namespaces, decorators, and the old module system are also pretty awkward when blending with modern javascript. Makes you want to add lint rules to prevent them from being used.

With the last release (2.1) maintaining typing definitions is mostly as optional as Flow, because TS now just assumes imports it cannot find are `any` type.

A lot of typings are now directly inside the NPM packages of the libraries themselves and install "automatically" for you; many other typings can be searched on NPM (primarily the @types/ scope).

I'm not sure this answers your question, but:

I've been working with TS for the past couple of years but now I'm working on a Flow project.

Flow doesn't even compare. It falls short on many things TS would immediately flag, and just feels less thought-out (subjective I know). Tooling support is terrible and while not the language's fault, it means it just doesn't help you as much as it could. Using Flow basically becomes an afterthought, a part of your build step, while with TS it's much easier to have that integrated into your development flow (via your editor of choice).

And honestly, some of the decisions around the language just feel strange. Not knowing what kind of bool to use [0] is pretty emblematic of where it is going as a language.

To me Flow is just half-helping in a way that TS is fully devoted to.

[0] http://stackoverflow.com/questions/40618817/flow-bool-boolea...

> It falls short on many things TS would immediately flag

I'm kind of curious what you've run into personally. Having a dependency without any type-defs get silently treated as `any` is my own beef, but I haven't hit much else yet.

(Some type-defs' use for `any` also gets my goat, such as Promise's catch argument and some of the lodash functions, but I'm considering that a separate thing.)

> And honestly, some of the decisions around the language just feel strange. Not knowing what kind of bool to use [0] is pretty emblematic of where it is going as a language.

This is more an existing JS weirdness (`true`/`false` vs `Boolean()`); Flow doesn't mess with runtime semantics, only adding a layer that you check with then strip out.

And TypeScript has the same thing:

  var a: boolean = new Boolean(1);
  
  // Produces:
  // NewTypering.ts(29,5): error TS2322: Type 'Boolean' is not assignable to type 'boolean'.
TypeScript's full error message on that last one is actually

  Type 'Boolean' is not assignable to type 'boolean'.
    'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.
«Having a dependency without any type-defs get silently treated as `any` is my own beef»

You can add the compiler flag --noImplicitAny to get errors if you prefer.

My colleague put it less cordially.

".... at least if they use flow, they are bagging up their shite which is better than a open field of the stuff".

I don't get the 'maintaining type definitions is hard' argument. It's super easy to do, especially when coupled with typewriter which will automatically generate types for your server side DTOs. Also having typings saves you an incredible amount of time with fast refactoring, auto-complete, and of course the type checking which saves countless hours of debugging the dumbest mistakes.

When you start talking about getting into code bases that you didn't personally write. The time savings and productivity benefits that TypeScript brings are immense.

I like Flow and I am actually using it right now, but I also see some negatives

It still feels like very much in beta. Things break often along the edges, there are things like interfaces that work only sometimes, the modules are always working strangely

Also, and that might be a personal thing, but for me, TypeScript itself has a more readable source code, since it's in TypeScript. Flow is in OCaml, which I cannot read.

On the other hand, I like how Flow is very "thin", and how I am just using ES6 with types "hints" on top; that's why I prefer Flow.

I've done some average sized projects in Flow and in TypeScript, and it's a lot more subtle IMO than most people would have it (especially people who only tried one, or only tried both cursively)

TypeScript absolutely has the better tooling. It's not even -close-. It's a little tricky though because a lot of FE devs these days use VIM or Sublime with a few plugins and a linter running in a terminal is as far as it goes, so explaining the importance of proper refactoring tool and semantic search is tough (no, using grep/ag/ack is not enough in a large code base, no matter how good you are with them).

On the other hand, the Flow checker is a lot more interesting, with more advanced call site analysis, and the type inference follows types a lot further (where you can type an entire file without any annotations, though Flow does require them on exports if you want imports in other files to be typed). That means functions with no annotations are much more frequently type checked and it's more useful during prototyping.

Flow is also a bit more careful about putting on the C#/Java lipstick (neither Flow nor TypeScript are actually java/C#-like, being much more functional and using structural typing as first class citizens, but TypeScript definitely LOOK the part to the untrained eyes, which makes developers used with those languages try to use the same patterns and heavily abuse classes instead of union types, etc. In Flow it's less of an issue).

Flow definitely causes a lot more surprises: call site analysis means error messages can be more confusing, and certain cases like inaccessible code path can cause some surprising scenarios.

flow-typed has many less type definitions, but they're generally higher quality. TypeScript's type definitions I found are very, very poor, as a relic of the days where versioning was an issue and many have not been fixed. You also have issues with useStrictNull not having been there all along causing problems. TypeScript however benefits heavily from having more libraries being native TypeScript, which is better than having good type definitions.

Finally, while TypeScript's tooling is vastly superior, Flow has the benefit of being parsable by Babel via Babylon, making large parts of the ecosystem a lot more Flow friendly. This came up recently with the amazing Prettier project being a non-starter for TypeScript users.

I've been hopping between vanilla JS, Flow and TypeScript continually...and no matter which one I use, I wish I was using another.

> TypeScript's type definitions I found are very, very poor, as a relic of the days where versioning was an issue and many have not been fixed.

I've always found it funny that DefinitelyTyped's tag line is "The repository for high quality TypeScript type definitions", but it's an absolutely disastrous system. If it's not a well-used library, definitions there will be woefully out of date. Versioning is a huge issue with it, so it's hard to figure out what definitions actually match the version library you're using. I can only admit that it's an effort that's better than nothing.

The few projects I added types to, the original project owners gladly accepted them into their main repos, which is great since types will "just work" without fuddling with @types packages.

I too feel that as a types contributor I've mostly given up on trying to contribute to DefinitelyTyped and try to contribute directly to library authors. I also think that DT has grown far too big and far too hard to contribute to, especially for fixes to types to small, lesser used libraries.
Talking about flow, I was wondering: couldn't something like that be implemented just with comments, leaving us with actually 100% valid javascript? Eg:

  // @param somestring [String] yadda yadda
  // @return [Boolean]
  function somefunction(somestring) {
    // @type [Boolean]
    var ret;

    ...

    return ret;
  }
This would remove any type of "lock in" if you want to use it...
I'd prefer that approach too, as I can also document things at the same time as providing type annotations; flow-jsdoc looks interesting, but I don't know how easy it would be to plug into a Babel/Webpack+Babel workflow:

https://github.com/Kegsay/flow-jsdoc

Might be worth pointing out, the "documentation" package[1] can be used to generate jsdoc annotations suitable for Google Closure compiler from Flow type annotations.

It can also build really nice HTML documentation to.

[1] https://www.npmjs.com/package/documentation

My biggest gripe with Flow is how buggy it is.

1. it often fails to find the type for an imported piece of code 2. more often than not refers to the type definition being a problem rather than whoever's calling a function with an incorrect type 3. it seems to have an issue with cache busting(?) (I `killall flow` multiple times per day to make sure it's not complaining about old code)

All in all I feel very sad for choosing Flow over TypeScript two weeks ago. We felt TS would be more invasive to our Webpack pipeline but I think I might just take a weekend to migrate over to TS...

TS seems to have a lot more type definitions available as well, a more active community perhaps?

Looking at the issue list of Flow I'm starting to suspect they're not very active in maintenance / issue handling. TS seems much more active.

Woo :) whenever I have to work with an old javascript code base now I always add typings to it first. It makes it orders or magnitude easier to work with and refactor after that.
I have to admit I am getting lost in all these new language constructs :(. I worry that soon I will not be able to read TS code of more experienced programmers.

That being said, the only way forward is to learn! But there seems to be total lack of solid learning resources with plentiful of examples and most importantly "best practices" that explain why the new construct is better and when to use it over the old way.