Closed
Description
- I have tried restarting my IDE and the issue persists.
- I have updated to the latest version of the packages.
- I have read the FAQ and my problem is not listed.
Repro
{
"rules": {
"@typescript-eslint/no-non-null-asserted-optional-chain": "error"
}
}
let foo1: { bar: { baz: string } } | undefined;
console.log(foo1?.bar!.baz);
Expected Result
ESLint reports error.
Actual Result
Infinite Loop.
Additional Info
I am using ESLint programmatically:
import { CLIEngine, Linter } from 'eslint';
const cli = new CLIEngine({});
cli.executeOnFiles('/path/to/the/file.ts');
But the script never ended. However this problem was not present in VSCode ESLint Plugin. I have no idea about what's happening. I am not sure the above code can reproduce the problem (because it is extracted from a large codebase).
I used the debugger to pause when infinite loop occurred. It ended up here:
There is an obvious logical error: the break
only breaks the switch
statement, meanwhile current.optional
is truthy, meaning current
is truthy. Theoretically THE LOOP WILL NEVER STOP WHEN A OPTIONAL CHAIN IS FOUND.
while (current) {
switch (current.type) {
case AST_NODE_TYPES.MemberExpression:
if (current.optional) {
// found an optional chain! stop traversing
break;
}
current = current.object;
continue;
case AST_NODE_TYPES.CallExpression:
if (current.optional) {
// found an optional chain! stop traversing
break;
}
current = current.callee;
continue;
default:
// something that's not a ChainElement, which means this is not an optional chain we want to check
return;
}
}
Versions
package | version |
---|---|
@typescript-eslint/eslint-plugin |
4.1.0 |
@typescript-eslint/parser |
4.1.0 |
TypeScript |
3.7.3 |
ESLint |
6.8.0 |
node |
12.18.2 |