Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript --strictNullChecks vs. flow's null checking

Tags:

typescript

If I run "typescript --strictNullChecks" over the code below, I get no errors. If I run flow over it, it gives me an error about type incompatibility of null vs. number. Why doesn't typescript also error on this? Is that a feature or an issue worth logging?

// @flow
var f = function f( x ) {
    var y = x * 2;
}
f(null);
like image 421
l00ser2410656 Avatar asked Jan 06 '23 10:01

l00ser2410656


1 Answers

TypeScript doesn't do call site analysis.

TypeScript sees this, which is OK:

var f = function f( x: any ) {
    var y = x * 2;
}
f(null);

Flow sees:

var f = function f( x: ??? ) {
    var y = x * 2;
}
f(null);

where ??? is determined by looking at the calls in the current file. In this case x has the bare type null and is in error.

Why doesn't TypeScript infer types from call sites? In general, the error messages a computer can generate from doing this are vague -- what you often see in Flow is that you pass the wrong kind of argument to a function, get an error in the body of the correctly-implemented function (or a downstream function), then have to work backwards to see where the offending argument originated. Sometimes this just isn't clear -- if half your code wrote fileName and half your code wrote filename and you pass a mix of those objects around, who's to say who's incorrect? The TypeScript answer is "put a type annotation explaining what you intended" so that you can get high-specificity errors.

And because this analysis is more expensive, it's not well-suited for whole-program analysis. So Flow only does this inference on a per-file basis, which means you generally want to have type annotations on every function at the "boundary" of a file and the files it interacts with. And since those boundaries are where most of the bugs are, it doesn't always buy you as much as it might seem at first blush.

like image 189
Ryan Cavanaugh Avatar answered Jan 21 '23 23:01

Ryan Cavanaugh