30

I'm working on an Electron application and I want to use async await in an anonymous function in my Main like this:

process.on("uncaughtException", async (error: Error) => {
  await this.errorHandler(error);
});

But this yields the Typescript error

Promise returned in function argument where a void return was expected.

I'm using Typescript 3.9.7 and Electron 9.2.0.

Why doesn't it allow me to use async/await?

mottosson
  • 3,283
  • 4
  • 35
  • 73
  • 2
    An `async` function *always* returns a promise, so it can't be passed where a void function is expected. Why not just call the error handler, what are you trying to wait for? – jonrsharpe Aug 19 '20 at 13:35
  • 1
    In general, don't pass `async` functions into things that won't use the promise they return. TypeScript is helping you avoid doing that with this error. – T.J. Crowder Aug 19 '20 at 13:37

4 Answers4

50

You can use an asynchronous IIFE inside the callback, like this:

process.on("uncaughtException", (error: Error) => {
  (async () => {
    await this.errorHandler(error);

    // ...
  })();
});

This ensures that the implicit return of the callback remains undefined, rather than being a promise.

Lionel Rowe
  • 5,164
  • 1
  • 14
  • 27
  • 1
    Just be sure to handle promise rejection correctly. – T.J. Crowder Aug 19 '20 at 13:37
  • 14
    Is there a good reason to do that, beyond removing the eslint error? – Henrique Bruno Nov 21 '20 at 17:56
  • 4
    @Henrique Bruno Functionally, no. Semantically, yes — it signals clearly that this is a "fire and forget" operation and that the callback itself doesn't do anything special with the asynchronous code (doesn't await it or do anything with the result). – Lionel Rowe Nov 22 '20 at 19:16
  • 1
    @LionelRowe Simple and mind expanding answer. Thanks! I will, however, keep this ESLint rule disabled as I think that it being enabled, adds an unnecessary complexity and verbosity level for my uses. – Henrique Bruno Nov 22 '20 at 21:52
  • I have a similar case here: onClick={ () => UtilClass.getName(a, b).then( (name) => { UtilClass.delete(name, x, y); }) } It is giving me @typescript-eslint/no-misused-promises error. How should I fix it in my case? – Tony Dec 09 '22 at 01:43
13

Fixed it, I found the answer below from here

 <div
  onClick={
    () => {
      void doSomethingAsync();
    }
  }
  onClick={
    () => {
      void (async () => {
        const x = await doSomethingAsync();
        doSomethingElse(X);
      })();
    }
  }
/>
Thanh Nhật
  • 777
  • 1
  • 7
  • 14
  • 15
    it works but it looks awfull, I'd rather disable the rule lol – Fer Toasted Nov 18 '22 at 00:44
  • I have a similar case here: onClick={ () => UtilClass.getName(a, b).then( (name) => { UtilClass.delete(name, x, y); }) } It is giving me @typescript-eslint/no-misused-promises error. How should I fix it in my case? – Tony Dec 09 '22 at 01:43
  • This actually affects the outcome of the callback in button elements. I've experienced a preventDefault() bug, it submits the form regardless. removing the void solved it. – Daniel Aviv Jul 03 '23 at 23:46
4

You can turn off this check (not the entire rule) with the help of checksVoidReturn option:

.eslinter.js

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

But I strongly recommend not to do this and rewrite your code using .then and .catch to avoid hitting this linter error.

You may also disable this rule inline with // eslint-disable-next-line @typescript-eslint/no-misused-promises comment above this particular occurrence along with a few lines of comment describing why you think this is okay to ignore the error.

Farzan
  • 745
  • 10
  • 25
-1

This is the official TS ESLint solution and I recommend you update your .eslintrc config file with:

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

Check this Pull Request for more info https://github.com/typescript-eslint/typescript-eslint/pull/4623