Reputation: 803
I seem to have an issue with Typescript typings on my Express Request object. The project for now exists out of 2 sub-projects (user-service and a common project which includes reusable Errors and Middlewares)
The common folder is installed as a dependency in the user-service like: "@myPackage/common": "file:../common",
In there I have a current-user middleware:
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
interface UserPayload {
id: string;
email: string;
}
declare global {
namespace Express {
interface Request {
currentUser?: UserPayload;
}
}
}
const currentUser = (
req: Request,
res: Response,
next: NextFunction,
) => {
if (!req.session?.jwt) {
return next();
}
try {
const payload = jwt.verify(
req.session.jwt,
process.env.JWT_KEY!,
) as UserPayload;
req.currentUser = payload;
} catch (err) {
console.error(err);
}
return next();
};
export default currentUser;
with a declared global for the currentUser property on the Request object.
In my user-service project I have the following route
import express, { Request, Response } from 'express';
import { Middlewares } from '@myPackage/common';
const router = express.Router();
router.get('/api/users/currentuser', Middlewares.currentUser, (
req: Request,
res: Response,
) => {
res.send({ currentUser: req.currentUser || null });
});
export default router;
On req.currentUser
I get the following error message:
Property 'currentUser' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'.
Shouldn't the package typings automatically be taken over in the code in which you import it? I hope I made myself clear on what the problem is :)
Upvotes: 1
Views: 1991
Reputation: 179
I've also always had trouble declaring a global namespace to attach types to express's request object. Found myself a solution using "declare module" instead of "declare global". So instead of
declare global {
namespace Express {
interface Request {
currentUser?: UserPayload;
}
}
}
maybe give the following approach a try:
declare module "express-serve-static-core" {
interface Request {
currentUser?: UserPayload;
}
}
Normally your currentUser property should also be available in other files with this approach, but you can of course export the manipulated Request interface if not.
Note that in most cases you will need to reference the "express-serve-static-core" module as this is where the Request interface is declared.
Upvotes: -1