Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strictNullChecks false positive when all possible conditions have been defined #27909

Closed
Ky6uk opened this issue Oct 15, 2018 · 4 comments · Fixed by #32695
Closed

strictNullChecks false positive when all possible conditions have been defined #27909

Ky6uk opened this issue Oct 15, 2018 · 4 comments · Fixed by #32695

Comments

@Ky6uk
Copy link

Ky6uk commented Oct 15, 2018

TypeScript Version: v3.1.3

Search Terms:
strictNullChecks, switch, case, condition, if, variable is used before being assigned.

Code

const enum Test {
  A, B
}

function test(x: Test) {
  let bork: string;

  switch (x) {
    case Test.A: {
      bork = 'a';

      break;
    }

    case Test.B: {
      bork = 'b';

      break;
    }
  }
  
  return bork;
  //     ^^^^
  //     Variable 'bork' is used before being assigned.
}

Expected behavior:
No errors here.

TS should know about all possible checks. Right now we can get some kind of error: Not all code paths return a value. in cases when we didn't define all possible cases or when default has been omited.

Actual behavior:
We got an error Variable is used before being assigned. It also happens with if-else-if variant.

Playground Link:
Click Me!

Related Issues:
Possible related issue: #27239. But this one is out of the loop.
Also: #9655, #10470, #17358, #20409, #23271.

@Ky6uk Ky6uk changed the title strictNullChecks false positive when switch-case covers all possible checks strictNullChecks false positive when all possible conditions have been defined Oct 15, 2018
@mattmccutchen
Copy link
Contributor

This is a design limitation: control-flow analysis (used by strictNullChecks as well as some other TypeScript features) isn't aware of exhaustiveness of if or switch statements. See #23271 (comment) for a list of related issues.

@Ky6uk
Copy link
Author

Ky6uk commented Oct 16, 2018

Alright, I see. Hope this will implemented in some way. Right now this is inconvenient to assign default value when it makes no sense and usage of @ts-ignore or ! just tickles my inner perfectionist. :(

@Ky6uk Ky6uk closed this as completed Oct 16, 2018
@lemoinem
Copy link

@mattmccutchen I'm curious why noImplicitReturns can detect such exhaustiveness, while strictNullChecks can't...

Example: https://www.typescriptlang.org/play/index.html#src=enum%20Foo%0D%0A%7B%0D%0A%20%20%20%20Foo%2C%0D%0A%20%20%20%20Bar%0D%0A%7D%0D%0A%0D%0Afunction%20fn2(foo%3A%20Foo)%3A%20%7B%20a%3A%20number%20%7D%0D%0A%7B%0D%0A%20%20%20%20let%20result%3A%20%7B%20a%3A%20number%20%7D%3B%0D%0A%0D%0A%20%20%20%20switch%20(foo)%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20case%20Foo.Foo%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20%7B%20a%3A%20Foo.Bar%20%7D%3B%0D%0A%20%20%20%20%20%20%20%20case%20Foo.Bar%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20%7B%20a%3A%20Foo.Foo%20%7D%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20return%20result%3B%20%2F%2F%20If%20we%20have%20%22Variable%20'result'%20is%20used%20before%20being%20assigned.%22%20here...%0D%0A%7D%0D%0A%0D%0Afunction%20fn1(foo%3A%20Foo)%3A%20%7B%20a%3A%20number%20%7D%0D%0A%7B%0D%0A%20%20%20%20switch%20(foo)%0D%0A%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20case%20Foo.Foo%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20a%3A%20Foo.Bar%20%7D%3B%0D%0A%20%20%20%20%20%20%20%20case%20Foo.Bar%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%20a%3A%20Foo.Foo%20%7D%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%2F%2F%20...Why%20don't%20we%20have%20%22Function%20lacks%20ending%20return%20statement%20and%20return%20type%20does%20not%20include%20'undefined'.%22%0D%0A%7D

Surely, if it's possible to detect for a return, it should be possible for variable initialization?

@mattmccutchen
Copy link
Contributor

@lemoinem noImplicitReturns has a special case for a switch statement that is the last statement in a function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants