It solves not having to write a bunch of tests that can trivially be caught by a program and never having to update or maintain those tests. It hits every code path automatically, you don't have to think of cases to try to hit edge cases.
- It type checks JSX - It supports some ES6 features others don't (like destructuring) as the build step - It has union types (TS will get those soon, already in master) - It does a lot more inference and a lot more assumptions. It assumes you won't multiply a string by a number for example (although technically '10' * 5 is legal in JS). So it's opinionated in that it enforces checks that rule out code that is legal but not likely intended in JS (an opinin I agree with).
Yes - it is possible to write tests and get good coverage and not use those tools - however static analysis can be very valuable in finding errors early. While I'm not sure I'd bother with explicit typing in this in smaller projects from the examples and unit tests it looks like it could find errors people would not easily notice otherwise. (Think JSHint, on steroids).
That said, only time will tell how good the implementation will really get in understanding your code.
you're not wrong, but out of curiosity, I just genuinely wonder how often modern programmers really hit type errors on smaller projects (obviously not FB size). I don't think I've ever had a type cast bug in my js code, provided we don't include accidental nulls in that statement. So in my experience, if I were ever told that I now had to always use annotations, I would feel like I was losing flexibility in the language for little gain. And I feel like the reason I never hit type issues, is because I write full test coverage, which in turn make it painfully obvious what is and is not expected in each method.
For the reasons above, I love the idea of this tool dynamically checking all my code paths, and looking for things that are likely mistakes or result in null exceptions.
But I'm afraid to recommend this to my boss, for fear that for now on, everything must be maximum static... everything annotated, no union types, etc.
Just my 2 cents.
Static typing also serve as a documentation, and enables "intellisense-coding" without having to google documentation every 2 minutes. Take this function signature from pythons standard library: subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())
Without documentation, can you answer: what is env? what is stdin? what values are allowed in creationflags? is it obvious that startupinfo should be a STARTUPINFO object?
Compare to a C# equivalent, FileStream Open(string path, FileMode mode, FileAccess access, FileShare share). Here it is obvious that FileAccess can only have one out of 3 available options in the enum since the autocomplete will only give you those three options.
Interstingly it's almost always the same kind of type error- accessing nested maps/arrays and forgetting to go deep enough before I call some method on the elements in that collection.
I can't remember one example of type error where I intended to call method on MyClassA and ended up trying to call it on MyClassB. But that may be the effect of my coding style (I'm not big fan of class hierarchies in js).
BTW it's funny how many times late binding was reinvented in j2ee ecosystem :)
However, whilst I never hit on basic type errors such as passing a string when I need an int - I regularly come across object type errors. I'll pass an object with a project_id property to a method that actually expects an id property. Not sure if flow can handle these - if it could it would be pretty amazing.
Today I got the order of parameters to a callback wrong ("error" was the last rather than the first parameter). The documentation didn't say anything about parameters, it only said that the callback would be called with a result. I had to look into the source code to discover the details. I am not sure if Flow would be able to catch this kind of bug but if so, it would certainly save me a lot of time.
In a dynamically-typed codebase, it's near impossible to have rare type-error occurrence because you're off-loading the type system into into the programmers head (which is subject to human fallibility - even when countered with excellent unit testing!)
Issues with null are much more common.
I frequently see methods incorrectly overidden. For example, the ancestor method effectively has a variadic argument list, but the descendant doesn't have as sophisticated argument handling and doesn't do the appropriate superFunc.apply(this, Array.prototype.slice.call(arguments, 0)) etc.
The (supposed) need to have "good code coverage" is itself a problem I'd like solved.
This tool claims it can do advanced inference. If it were possible to hook it up to an editor or IDE to analyse existing untyped js in this way it could be invaluable.
As others have said, I love the approach of inference giving static type benefits, for free. If you get tooling support, at no extra work, why not adopt it?
But static types can be a hard sell for JS programmers. What sort of reception has it gotten inside facebook?
Typescript (from MS) sounds a lot like what you describe - it doesn't change Javascript, it just adds types to it (and makes some ES6 features available), and it puts a lot of work into playing nice with the wider JS ecosystem (e.g. via the definitelytyped project, which integrates type definitions for most popular "third-party" javascript libraries).
> That said, I am curious what solutions this solves that isn't already solved by enforcing good code coverage. Full disclaimer, the largest js projects I've worked on were in the tens of thousands of lines, not hundreds of thousands, but type checking just seemed completely unnecessary provided a good coding guide and test coverage were maintained and enforced.
Perfect testing can do everything a type system can. But a type system can do it with less programmer effort, much lower maintenance overhead, and in a standard form that makes it easier to maintain. So you can do the same thing but cheaper - or, more realistically for how software is developed in most companies, you can get better reliability for the same engineering budget.
The Google Closure Compiler (https://developers.google.com/closure/compiler/) has been around for years and years.
It does everything you mentioned (100% optional type annotations, type inference), plus more (dead code removal, inlining, compiler-time constants).
+ it's not incremental hence unusably slow, requires Java. No, Closure is not the same as Flow even from a brief look at both.
> code intelligence, which aids code maintenance, navigation, transformation, and optimization
I suspect that for facebook, this could be just as important, if not more so, than code quality benefits.
I specifically didn't send this tool to the team I work on, because my team lead is a sql / java / c# guy who loves static languages, and only touches the front end with a stick if he has to, and then only some basic jQuery or angular.
I've sold him on jasmine and requiring front end test coverage, recently. But right before I hit the send button I realized that if I sent him this tool, I'd never be allowed to use dynamic typing or non annotated functions/arguments in js ever again.
Hence my question : /
That said, I am curious what solutions this solves that isn't already solved by enforcing good code coverage. Full disclaimer, the largest js projects I've worked on were in the tens of thousands of lines, not hundreds of thousands, but type checking just seemed completely unnecessary provided a good coding guide and test coverage were maintained and enforced.