-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Unreachable 'for' clause doesn't correctly narrow #11821
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
Comments
@Aleksey-Bykov Not super familiar with the flow based type checking, but did you mean to have an
|
@masaeedu the comparison is the middle clause of a for loop, not an expression statement |
@Aleksey-Bykov I can't reproduce this. As usual, we'd really prefer a self-contained repro and a descriptive title on bugs |
@RyanCavanaugh My bad. I can reproduce this, you need to enable |
@RyanCavanaugh updated the title, |
it's like you are giving me a favor of considering bugs that i found in your product, sorry for doing it and making you upset |
function foo() {
for (let current: string | undefined = 'oops'; true; current = current.substr(1)) {
// Incorrect error in third clause
return;
}
} |
@Aleksey-Bykov apology accepted |
@RyanCavanaugh Isn't the error only incorrect in the case where the middle clause narrows the loop variable? |
The narrowing of the middle clause is irrelevant because we never assign anything possibly-undefined to |
@RyanCavanaugh Well in the original case |
@RyanCavanaugh, you made a repro that doens't really cover the reported case: notice that the first snippet works, the problem reveals itself in the presence of a body |
More accurately, this seems to happen when the end flow point of the |
oh, you used the return for a body, nevermind |
@RyanCavanaugh Here's what I'm trying to say interface Node {
parent: Node | undefined;
}
// This currently fails to compile. After the fix it SHOULD compile
function foo1(node: Node): boolean {
for (let current: Node | undefined = node; current !== undefined; current = current.parent) {
continue;
}
return false;
}
// This currently fails to compile. After the fix it SHOULD NOT compile
function foo2(node: Node): boolean {
for (let current: Node | undefined = node; 1 === 1; current = current.parent) {
continue;
}
return false;
} The second case should fail because the conditional clause does not do the appropriate narrowing, regardless of whether the bottom of the loop body is reachable. |
The second case shouldn't fail. There are no assignments to interface Node {
parent: Node;
}
function foo2(node: Node): boolean {
for (let current: Node | undefined = node; 1 === 1; current = current.parent) {
// continue;
}
return false;
} Note that there should never be a difference between a for(a; ; c) {
// code
// block-terminal continue
continue;
} and a for(a; ; c) {
// code
} |
We're travelling up the parent chain of a |
@RyanCavanaugh You can verify that the latter fails at runtime where the former does not: interface N {
parent?: N;
}
let n1: N = {}, n2: N = {};
n1.parent = n2;
// This currently fails to compile. After the fix it SHOULD compile
function foo1(node: N): boolean {
for (let current: N | undefined = node; current !== undefined; current = current.parent) {
continue;
}
return false;
}
// This currently fails to compile. After the fix it SHOULD NOT compile
function foo2(node: N): boolean {
for (let current: N | undefined = node; 1 === 1; current = current.parent) {
continue;
}
return false;
}
console.log('foo1: ', foo1(n1)); // false
console.log('foo2: ', foo2(n1)); // Uncaught TypeError: Cannot read property 'parent' of undefined |
Forward-duping this to #26914 |
nightly build Oct 24, 2016
The text was updated successfully, but these errors were encountered: