Skip to content

Uninitialized variables work around strictNullChecks (follow-up to #13884) #23305

Closed
@agopshi

Description

@agopshi

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:

#13884, #9998


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();
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort: ModerateRequires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual".Help WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions