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

TS don't consider multi variable control flow analysis #23301

Closed
tinganho opened this issue Apr 10, 2018 · 6 comments
Closed

TS don't consider multi variable control flow analysis #23301

tinganho opened this issue Apr 10, 2018 · 6 comments
Labels
Duplicate An existing issue was already created

Comments

@tinganho
Copy link
Contributor

TypeScript Version: 2.7.0-dev.201xxxxx

Search Terms:
multi variable control flow analysis typescript

Code

declare const cleft: number | undefined;
declare const cright: number | undefined;

if (typeof cleft === 'number') {
    cleft.toExponential();
}
else {
    cleft.toExpontential(); // Error
}

if (typeof cleft === 'undefined' &&
    typeof cright === 'undefined')
{
    cleft.toExponential(); // Error
}
else if (typeof cleft === 'undefined' &&
    typeof cright !== 'undefined')
{
    cleft.toExponential(); // Error
}
else if (typeof cleft !== 'undefined' &&
    typeof cright === 'undefined')
{
    cleft.toExponential();
}
else {
    cleft.toExponential(); // Error But shouldn't
}

Expected behavior:
No error on the last else body.

Actual behavior:
Error on the last else body.

Playground Link:
http://www.typescriptlang.org/play/#src=%0Adeclare%20const%20cleft%3A%20number%20%7C%20undefined%3B%0Adeclare%20const%20cright%3A%20number%20%7C%20undefined%3B%0A%0Aif%20(typeof%20cleft%20%3D%3D%3D%20'number')%20%7B%0A%20%20%20%20cleft.toExponential()%3B%0A%7D%0Aelse%20%7B%0A%20%20%20%20cleft.toExpontential()%3B%20%2F%2F%20Error%0A%7D%0A%0Aif%20(typeof%20cleft%20%3D%3D%3D%20'undefined'%20%26%26%0A%20%20%20%20typeof%20cright%20%3D%3D%3D%20'undefined')%0A%7B%0A%20%20%20%20cleft.toExponential()%3B%20%2F%2F%20Error%0A%20%20%20%20%0A%7D%0Aelse%20if%20(typeof%20cleft%20%3D%3D%3D%20'undefined'%20%26%26%0A%20%20%20%20typeof%20cright%20!%3D%3D%20'undefined')%0A%7B%0A%20%20%20%20cleft.toExponential()%3B%20%2F%2F%20Error%0A%7D%0Aelse%20if%20(typeof%20cleft%20!%3D%3D%20'undefined'%20%26%26%0A%20%20%20%20typeof%20cright%20%3D%3D%3D%20'undefined')%0A%7B%0A%20%20%20%20cleft.toExponential()%3B%0A%7D%0Aelse%20%7B%0A%20%20%20%20cleft.toExponential()%3B%20%2F%2F%20Error%0A%7D%0A

Related Issues:

@tomrav
Copy link

tomrav commented Apr 10, 2018

Just curious, in the playground example you provided, there is no error in the last else block.
Seems to match your expected behavior. Is it possible that this issue is fixed in the current version?

@tinganho
Copy link
Contributor Author

The flag strictNullChecks is not reflected on the URL. And I cannot share it with the option on. But if you set the flag, you can see the error

@mhegazy mhegazy added the Bug A bug in TypeScript label Apr 10, 2018
@mhegazy mhegazy added this to the TypeScript 2.9 milestone Apr 12, 2018
@tinganho
Copy link
Contributor Author

Here is another example, a is assigned on all possible code paths below:

declare let some1: boolean;
declare let some2: boolean;

let a: string;
if (some1) {
    if (some2) {
        a = '';
    }
}
else {
    a = ''
}

if (some1 && !some2) {
    a = ''
}

f(a); // Error: 'a' is used before assigned

function f(p: string) {

}

http://www.typescriptlang.org/play/#src=declare%20let%20some1%3A%20boolean%3B%0Adeclare%20let%20some2%3A%20boolean%3B%0A%0Alet%20a%3A%20string%3B%0Aif%20(some1)%20%7B%0A%20%20%20%20if%20(some2)%20%7B%0A%20%20%20%20%20%20%20%20a%20%3D%20''%3B%0A%20%20%20%20%7D%0A%7D%0Aelse%20%7B%0A%20%20%20%20a%20%3D%20''%0A%7D%0A%0Aif%20(some1%20%26%26%20!some2)%20%7B%0A%20%20%20%20a%20%3D%20''%0A%7D%0A%0Af(a)%3B%0A%0Afunction%20f(p%3A%20string)%20%7B%0A%0A%7D

@ethanresnick
Copy link
Contributor

I think the below might be the same issue, but not sure. If it isn't, I'm happy to open a new issue:

declare const a: object | undefined;
declare const b: object | undefined;

function requiresObject(it: object) { return; }

function x() {
  if (!a && !b) {
    return true;
  }

  return a
    ? false
    : requiresObject(b); // Error: warns that b is possibly undefined, when we know it isn't.
}

@mhegazy mhegazy modified the milestones: TypeScript 3.0, TypeScript 3.1 Jul 2, 2018
@ahejlsberg
Copy link
Member

These are all examples of design limitations in the control flow analyzer. We're tracking the issue in #12184 so I'm going to close this as a duplicate.

@ahejlsberg ahejlsberg removed their assignment Aug 17, 2018
@ahejlsberg ahejlsberg added Duplicate An existing issue was already created and removed Bug A bug in TypeScript labels Aug 17, 2018
@ahejlsberg ahejlsberg removed this from the TypeScript 3.1 milestone Aug 17, 2018
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

6 participants