Typing Request in express gives type error using zod with middleware

Issue

Using express, typescript and zod and getting a type error on the Request type.

// validator
import {Request, Response, NextFunction} from "express";
import {Schema} from "zod";

export const validate = (schema: Schema) => (req: Request, res: Response, next: NextFunction) => {
  const input = schema.safeParse(req);
  if (!input.success) return res.status(400).send(input);

  return next();
};
// endpoint
import {Request, Response} from "express";

export function get(req: Request<{id: number}>, res: Response) {
  res.status(200).json({success: true});
}
// router
import {Router} from "express";
import {validate} from "./validator";
import {get} from "./endpoint";

const validationSchema = z.object({
 params: z.object({id: z.number()})
});

const router = Router();
/* type error (no overloads match this call) 
* typeof params is incompatible 
*  Property 'id' is missing in type 'ParamsDictionary' but required in type '{ id: number; }'
*/
router.get("/:id", validate(validationSchema), get);

I don’t get this error without the validate middleware, but I can’t figure out why that is causing the types to change. I know that the router.get call is not picking up on the :id.

Any help appreciated.

I should note, if I use a post request with the body validated I do not have this issue.

Solution

Whenever request params are parsed by express, they come in as string, so the get controller should be –

export function get(req: Request<{ id: string }>, res: Response) {
    res.status(200).json({ success: true });
}

That should take care of the typings issue, however, your validation with zod will fail, you’ll need to modify that.

Answered By – 0xts

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published