I have the following endpoint setup to reset a database after test runs:
import { getConnection } from 'typeorm';
import express from 'express';
const router = express.Router();
const resetDatabase = async (): Promise<void> => {
const connection = getConnection();
await connection.dropDatabase();
await connection.synchronize();
};
// typescript-eslint throws an error in the following route:
router.post('/reset', async (_request, response) => {
await resetTestDatabase();
response.status(204).end();
});
export default router;
The entire route since async
is underlined with a typescript-eslint error Promise returned in function argument where a void return was expected.
The app works perfectly but I'm not sure if I should be doing a safer implementation or just ignoring/disabling Eslint for this one. Any idea of what's wrong with that code?
This rule aims to prevent a likely common performance hazard due to a lack of understanding of the semantics of async function. If you do not want the performance benefit of avoiding return await If you want the functions to show up in stack traces (useful for debugging purposes) This rule was introduced in ESLint v3.10.0.
As mentioned above, the eslint-plugin-no-floating-promise rule is a great way to make sure you don't accidentally forget to use await in your async functions. If you're working in JavaScript and your project already uses eslint, adding eslint-plugin-no-floating-promise is as easy as adding the plugin to your .eslintrc config file:
Just as before, the repository for the tutorial is mwanago/express-typescript. If you find it helpful, feel free to give it a star. In the previous part of the tutorial, we wrote a handler function to return a post with a specific ID:
Using return await inside an async function keeps the current function in the call stack until the Promise that is being awaited has resolved, at the cost of an extra microtask before resolving the outer Promise. return await can also be used in a try/catch statement to catch errors from another function that returns a Promise.
It seems you are using the no-misused-promises rule which states that you cannot return Promise<void>
in a place where void
is expected.
This means that you cannot return Promise<void>
from your Express handler because the return type of RequestHandler
from the library specifies that the return type should be void
. I would suggest that you change it to return Promise<Response>
by adding a simple return
keyword:
import { getConnection } from 'typeorm';
import express from 'express';
const router = express.Router();
const resetDatabase = async (): Promise<void> => {
const connection = getConnection();
await connection.dropDatabase();
await connection.synchronize();
};
// typescript-eslint throws an error in the following route:
router.post('/reset', async (_request, response) => {
await resetTestDatabase();
return response.status(204).send(); // <----- return added here
});
export default router;
The other option would be to avoid using async/await
:
router.post('/reset', (_request, response) => {
resetDatabase().then(() => response.status(204).send());
});
I found a solution that doesn't involves using then()
and let you use the abstraction of async without getting cursed by the eslint, there's two solutions (but i recommend more the second one)
This is basic using a async inside the void like this:
router.post('/reset', (_request, response) => {
(async () => {
await resetTestDatabase();
response.status(204).end();
})()
});
The second option is to you use it as an async, as Always, but say "hey TypeScript, nothing is wrong here hehe" with the "as" keyword
import { RequestHandler } from 'express'
router.post('/reset', (async (_request, response) => {
await resetTestDatabase();
response.status(204).end();
}) as RequestHandler);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With