express-async-handler icon indicating copy to clipboard operation
express-async-handler copied to clipboard

Typescript types for handler arguments are "unknown"

Open 0x80 opened this issue 2 years ago • 4 comments

If I define a handler like this:

const router = express.Router();

router.get(
  "/verify-email",
  asyncHandler(async (req, res) => { }))

TS complains that the types of req and res are unknown and so I can't use any of their methods.

Any idea what might be causing this? I've tried both TS version 4.6 and 4.9 and using express-async-handler 1.2.0 and express 4.17.1

If I try to explicitly type req to express.Request I get "Type 'unknown' is not assignable to type 'Request<ParamsDictionary>"

0x80 avatar Dec 08 '22 13:12 0x80

Same issue here, have you found any solution @0x80 ?

wzomer avatar Dec 27 '22 20:12 wzomer

@wzomer No, unfortunately not. I tried to set some yarn resolutions for types but it didn't make a difference. I am a little tired of running into typing problems with Express so I am now investigating a migration to Fastify...

0x80 avatar Dec 28 '22 12:12 0x80

This handwritten async handler works with these package versions:

  • "typescript": "^5.0.4"
  • "@types/express": "^4.17.17"
  • "express": "^4.18.2"
import { RequestHandler, NextFunction } from 'express';

// Generic parameters just copied from RequestHandler
export const asyncHandler = <
  P,
  ResBody,
  ReqBody,
  ReqQuery,
  LocalsObj extends Record<string, any> = Record<string, any>
>(
  fun: (...args: Parameters<RequestHandler<P, ResBody, ReqBody, ReqQuery, LocalsObj>>) => void,
) => (...args: Parameters<RequestHandler<P, ResBody, ReqBody, ReqQuery, LocalsObj>>) => {
  const next = args[args.length - 1];
  Promise.resolve(fun(...args)).catch(next as NextFunction)
}

Voronar avatar Jun 01 '23 11:06 Voronar

I've had a small issue with the generic definition while using this, and copy-pasting definition from RequestHandler helped:

<
    P = core.ParamsDictionary,
    ResBody = any,
    ReqBody = any,
    ReqQuery = qs.ParsedQs,
    LocalsObj extends Record<string, any> = Record<string, any>
  >

piotrnajda3000 avatar Jul 23 '24 08:07 piotrnajda3000