Improved any Inference
Previously, if TypeScript couldn’t figure out the type of a variable, it would choose the any
type.
let x; // implicitly 'any'
let y = []; // implicitly 'any[]'
let z: any; // explicitly 'any'.
With TypeScript 2.1, instead of just choosing any
, TypeScript will infer types based on what you end up assigning later on.
This is only enabled if —noImplicitAny
is set.
Example
let x;
// You can still assign anything you want to 'x'.
x = () => 42;
// After that last assignment, TypeScript 2.1 knows that 'x' has type '() => number'.
let y = x();
// Thanks to that, it will now tell you that you can't add a number to a function!
console.log(x + y);
// ~~~~~
// Error! Operator '+' cannot be applied to types '() => number' and 'number'.
// TypeScript still allows you to assign anything you want to 'x'.
x = "Hello world!";
// But now it also knows that 'x' is a 'string'!
x.toLowerCase();
The same sort of tracking is now also done for empty arrays.
A variable declared with no type annotation and an initial value of []
is considered an implicit any[]
variable.However, each subsequent x.push(value)
, x.unshift(value)
or x[n] = value
operation evolves the type of the variable in accordance with what elements are added to it.
function f1() {
let x = [];
x.push(5);
x[1] = "hello";
x.unshift(true);
return x; // (string | number | boolean)[]
}
function f2() {
let x = null;
if (cond()) {
x = [];
while (cond()) {
x.push("hello");
}
}
return x; // string[] | null
}