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:
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?
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
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
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.
}
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.
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
Most helpful comment
The flag
strictNullChecksis 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