Description
This is a follow-up to #13884, where @RyanCavanaugh asked me to open a new issue.
tl;dr: Now that there is strictPropertyInitialization
, it seems that there should also be an analogous strictLocalInitialization
.
TypeScript Version: 2.8
Search Terms: uninitialized local variables, strict local variables, strictLocalInitialization, strictPropertyInitialization, strictNullChecks
Code
let x: number[]; // No definite assignment assertion.
// x.toString(); // Compile-time error. Yay!
function foo() {
x.toString(); // No compile-time error, but throws an exception. :(
}
foo();
Slightly more interesting:
function fooFactory() {
let x: number; // Inaccessible from anywhere but `foo()` below.
return {
foo() {
// Guaranteed to throw an exception since `x` can't change.
return x.toString();
}
};
}
Expected behavior:
If an imaginary --strictLocalInitialization
flag is enabled, these snippets should each result in a compile-time error.
To resolve such an error, one would need to:
A) Initialize the variable in a way that the TypeScript compiler understands (e.g. immediately, or before referencing it in a closure).
-OR-
B) Use a definite assignment assertion. It seems that this issue would come up naturally when discussing definite assignment assertions for local variables. Instead, the example provided in the blog feels contrived and wouldn't be a problem if it weren't for control flow analysis limitations.
-OR-
C) Explicitly mark the variable as potentially undefined
, forcing callers to acknowledge that it may not be set.
Actual behavior:
No compile-time errors, but obvious run-time errors.
Playground Link:
Link (enable strictNullChecks
)
Related Issues:
Understandably, this may not be as simple as strictPropertyInitialization
, but I feel it needs a discussion none the less. The fooFactory()
example above is analogous to this Foo
class, which correctly emits a compile-time error under strictPropertyInitialization
:
class Foo {
private x: number; // Compile-time error!
foo() {
// `x` isn't initialized! But it's OK, compile-time error above.
return this.x.toString();
}
}