This particular scenario is related to a recent PR that introduces control flow analysis (CFA) for variables implicitly typed as any
In the given example, variables x and y are implicitly assigned types of any
, but through control flow analysis, their actual types can be determined at each reference. As a result, no errors occur even when the code is compiled with --noImplicitAny
.
This analysis specifically applies to
[...] let
and var
declarations without type annotations and either lacking an initial value or being initialized with null
or undefined
.
Let's examine what happens in your specific case:
// By assigning null to x without a declared type, the new CFA comes into play
let x = null;
// As x was previously set to null, its type is known to be null
// The type of y depends on x, resulting in y being assigned the type null.
// Since y does not receive the null literal directly, no special CFA triggers for y
let y = x;
// Because x lacks a type annotation, it can accommodate any type like number
x = 1;
// As y already had a declared type (null), attempting to assign a number will cause an error
y = 1;
// With earlier assignments, x now stands as a number
x.toExponential()
Assigning a value to x
behaves like any
, allowing flexibility in assigning various types. However, its usage within expressions determines its type based on previous assignments.