This innocently seeming code is remarkably more complex to infer, and Typl correctly reports an error like a champ (where TS and Flow do not):
var y = foo(3);
var z = "hello" + y;
function foo(x) {
return x;
}
Here, we want the + operation to report an error because it's mixed types (string and number).
How that happens is, on the first pass, we don't know about foo(..) the function yet when we get to foo(3). So, we mark that we need to come back to it on another pass. Then, we find the function foo(..), but it doesn't have any annotated types.
On pass 2, we imply the x parameter as number from the foo(3) call. But we still don't know the return value of foo(..) to be able to imply a type for y. At the end of pass 2, we figure out the return type of foo(..) as number.
Finally, on pass 3, we can imply type number to y, and then we can validate the string + number needs to report an error!
(pass 1) ------------------------
Implying z as inferred-type 'string', at line 2, column 4
Implying foo as inferred-type 'func', at line 4, column 0
Function 'foo' signature: {"type":"func","params":[{"inferred":"unknown"}],"hasRestParam":false,"return":{"default":true,"inferred":"undef"}}, at line 4, column 0
(pass 2) ------------------------
Implying parameter x from argument, as inferred-type 'number', at line 4, column 13
Function 'foo' signature: {"type":"func","params":[{"inferred":"number"}],"hasRestParam":false,"return":{"inferred":"number"}}, at line 4, column 0
(pass 3) ------------------------
Implying y as inferred-type 'number', at line 1, column 4
Binary `+` operation, mixed operand types: type 'number' doesn't match type 'string', at line 2, column 8
Function 'foo' signature: {"type":"func","params":[{"inferred":"number"}],"hasRestParam":false,"return":{"inferred":"number"}}, at line 4, column 0
This innocently seeming code is remarkably more complex to infer, and Typl correctly reports an error like a champ (where TS and Flow do not):
Here, we want the
+operation to report an error because it's mixed types (string and number).How that happens is, on the first pass, we don't know about
foo(..)the function yet when we get tofoo(3). So, we mark that we need to come back to it on another pass. Then, we find the functionfoo(..), but it doesn't have any annotated types.On pass 2, we imply the
xparameter asnumberfrom thefoo(3)call. But we still don't know the return value offoo(..)to be able to imply a type fory. At the end of pass 2, we figure out the return type offoo(..)asnumber.Finally, on pass 3, we can imply type
numbertoy, and then we can validate thestring + numberneeds to report an error!