Skip to content

Incorrect error of use of unassigned variable #13811

Closed

Description

@NN---

TypeScript Version: 2.1.5
strictNullChecks: true

Code

let a: {};

if (!a) { // <!-- Error
   ....
}

Expected behavior:
Code compiles fine.

Actual behavior:
Use of unassigned variable.

Activity

  1. devdoomari commented on Feb 1, 2017

    @devdoomari

    a has the type of {}, and has no value assigned.
    i.e. your code is equivalent to:

    let a: {} = undefined;
    

    so what you wanted:

    let a = {}; // not let a: {}
    
  2. NN--- commented on Feb 1, 2017

    @NN---
    Author

    devdoomari (@devdoomari) It is not what I want.
    I want to have it undefined and assign it only if it is undefined.

    Full code:

    let a: {};
    
    for (const x of y) {
      if(x.q) {
        a =x.q;
        break;
      }
    }
    
    // Assign default value if couldn't assign before
    if (!a) {
      a = {};
    }
  3. ahejlsberg commented on Feb 1, 2017

    @ahejlsberg
    Member

    The control flow checker (in strict null checks mode) assures that you'll never accidentally observe undefined in a variable unless the type of the variable allows it. Your program logic is constructed such that undefined is actually a permitted value (at least in parts of the logic), so I'd recommend including undefined in the type of a:

    let a: {} | undefined;

    The problem with your suggestion is that we'd no longer catch this:

    let a: string;
    // Intended to have assignment here, but forgot
    if (!a) {
        // Think I have an empty string, but I have undefined
    }
  4. NN--- commented on Feb 1, 2017

    @NN---
    Author

    Anders Hejlsberg (@ahejlsberg) What about this case ?

    I would expect it compiling fine since I am checking against undefined.

    let a: number;
    if (typeof a !== "undefined") {
    	a = 1;
    }
  5. ahejlsberg commented on Feb 1, 2017

    @ahejlsberg
    Member

    I think the same argument holds. If the declared type of a variable does not include undefined, the control flow analyzer takes it to mean you never want to observe the variable in an uninitialized state (in any way). I think the consistency of that is important, particularly since you can just add undefined to the type in cases where you want to do those types of checks.

  6. NN--- commented on Feb 2, 2017

    @NN---
    Author

    That's what I ended with.
    Thanks.

  7. NN--- commented on Feb 6, 2017

    @NN---
    Author

    Anders Hejlsberg (@ahejlsberg)
    I feel that there is a need for language construct or helper which tests for null or undefined.
    Currently I use "if(a) {..}" but if type of 'a' changes to string or number, this test will not be correct.

    I feel more safe using this helper now.

    function isNullOrUndefined<T>(obj: T | null | undefined): obj is null | undefined {
    	return typeof obj === "undefined" || obj === null;
    }
    
    if (!isNullOrUndefined(a)) { ... }

    But prefer to have something in the language like:

    iff (a) { ... }
  8. ahejlsberg commented on Feb 6, 2017

    @ahejlsberg
    Member

    Adding entirely new statements beyond what JavaScript has is definitely out of scope for TypeScript. To check if a value is null or undefined in JavaScript, just use x == null. See more discussion here.

  9. NN--- commented on Feb 6, 2017

    @NN---
    Author

    Thanks.
    Didn't think about this pattern

  10. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions