I am currently utilizing express version 4.19.2
(the latest available at the time of writing)
This is how I have declared the generic type Request
interface ParamsDictionary {
[key: string]: string;
}
interface Request<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>,
> extends core.Request<P, ResBody, ReqBody, ReqQuery, Locals> {}
I am attempting to override 'P' or 'Params', in order to reference the actual type within my route handler. However, I encountered this error:
Type '(req: Request<ItemParam, unknown, ItemBody, unknown, JwtUser>, res: Response, next: NextFunction) => Promise<void>' is not assignable to type 'RequestHandler<ParamsDictionary, unknown, ItemBody, ParsedQs, JwtUser>'
Types of property 'params' are incompatible. Property 'itemId' is missing in type 'ParamsDictionary' but required in type 'ItemParam'
Here are snippets from my code:
interface ItemParam {
itemId: string;
}
const myHandler = async (
// ✅ No TypeScript error here
req: Request<ItemParam, unknown, ItemBody, unknown, JwtUser>,
res: Response,
next: NextFunction,
): Promise<void> => {
const { itemId } = req.params; // ✅ Can refer to itemId
const { amount } = req.body; // ✅ Can refer to amount
};
// ❌ However, I encounter an error in the route
router.route('/:itemId').put(
validate({
params: {
itemId: Joi.string().required(),
},
}),
myHandler, // ❌ Error occurs as shown above
);
No TypeScript error occurs if I remove 'validate':
// ✅ This works
router.route('/:itemId').put(
myHandler,
);
I also do not receive an error if I override my handler like this:
// ✅ This works
Request<{ itemId: string }, unknown, PlaceBidItemBody, unknown, JwtUser>
While I can use the above workaround, could someone please help me understand the issue or confirm if this is a bug in express?
UPDATE / POSSIBLE SOLUTION I modified the ItemParam type to:
interface ItemParam {
itemId: string;
[key: string]: string;
}
I prefer not to extend from ParamsDictionary
since it is part of the pre-included package express-server-static-code
, and generally not recommended to reference anything from packages you did not explicitly install.
If anyone could help me grasp why the original ItemParam
is not directly compatible with ParamsDictionary
, I would greatly appreciate it!