typescripteslinttypescript-eslint

"@typescript-eslint/no-misused-promises" for removing of async event handlers from DOM elements case


In below example, the async event listener is being removed from the HTMLElement. It has been treated as @typescript-eslint/no-misused-promises by the TypeScript ESLint plugin:

let button: HTMLELement;

// ...

async function hideAndUnmountSnackbar(): Promise<void> {
  // ...
}

// ESLint: Promise returned in function argument where a void return was expected.(@typescript-eslint/no-misused-promises)
button.removeEventListener("click", hideAndUnmountSnackbar);

I have checked the documentation for the rule but have not found an example similar to mine. However, to disable this rule by eslint-disable-next-line comment, some justification is required.

Is there such justification, or I just doing something wrong?


Solution

  • The rule also check for void returns and do not allow Promise returning methods in those cases.

    Event listeners return void, and we are returning a Promise<void>. That is the crux of the problem.

    checksVoidReturn is the configuration. The doc mentions how to switch it off:

    {
      "@typescript-eslint/no-misused-promises": [
        "error",
        {
          "checksVoidReturn": false
        }
      ]
    }
    

    The above rule might be too broad for some cases, and the most specific rule you can use to fix this is by not allowing the rule only for arguments:

    {
      "@typescript-eslint/no-misused-promises": [
        "error",
        {
          "checksVoidReturn": {
            "arguments": false
          }
        }
      ]
    }
    

    Playground


    Note that this would have also worked: button.removeEventListener("click",() => { hideAndUnmountSnackbar() });.