Skip to content

[no-non-null-asserted-optional-chain] Possible Infinite Loop #2521

Closed
@hjkcai

Description

@hjkcai
  • 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:

https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts#L116

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    accepting prsGo ahead, send a pull request that resolves this issuebugSomething isn't workingpackage: eslint-pluginIssues related to @typescript-eslint/eslint-plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions