2

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?

HigoChumbo
  • 155
  • 1
  • 8
  • 1
    I put this into the Typescript playground and it compiles without any errors so I don't think anything is wrong with the code. Maybe if you share your linting configuration we can get to the bottom of it. – cdimitroulas Apr 15 '21 at 18:46
  • 1
    Actually scratch that, I've checked what linting rule causes this and I'll write a proper answer – cdimitroulas Apr 15 '21 at 18:48

1 Answers1

1

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());
});
cdimitroulas
  • 1,576
  • 8
  • 17
  • Thank you! The second solution works, but adding the return to the first one keeps throwing the error, it really feels like eslint does not like that async. The rule is indeed `no-misused-promises`, forgot to mention it. Any idea of what might be happening with async await? I'm actually trying to get rid of .then()s for consistency =) –  HigoChumbo Apr 15 '21 at 20:14
  • 1
    When you add `async` to a function, it automatically makes the return type a `Promise`. If you were to return nothing as you do in your `async` function, the return type is `Promise` instead of just `void`. Honestly, I'm not sure that linting rule is worth it so I would be tempted to disable it. – cdimitroulas Apr 15 '21 at 20:39
  • 1
    Maybe you can try adding a type annotation to your handler. Like `async (_request, response): Promise => {` – cdimitroulas Apr 15 '21 at 20:41
  • 2
    His majesty doesn't like it. There is only so much time one can spend trying to appease Typescripot :P I'll just leave the then(), thanks again mate! –  HigoChumbo Apr 15 '21 at 21:31
  • Is there any way to solve this without then()? – Rouz May 27 '21 at 13:42