I'm working on creating a "CurrentUserMiddleware" within NestJS that I can implement globally. I'm using Express (not Fastify) in my implementation of NestJS. I'm trying to update / amend the "Request" interface packaged into "Express" with a new optional key / value pair (field) that is represented by a User Entity in NestJS.
I've resolved the original problem (sort of) by performing a global declaration, adding in the new field accordingly, however I get an error as a result of my linter: ES2015 module syntax is preferred over namespaces.
Looking at the documentation for TypeScript, it seems like the use of namespaces
has been deprecated. How can I make my change to the "Request" interface without making the linter mad?
The code for my current-user.middleware.ts
file can be found below:
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { UsersService } from '../users.service';
import { User } from '../user.entity';
declare global {
namespace Express {
interface Request {
currentUser?: User;
}
}
}
@Injectable()
export class CurrentUserMiddleware implements NestMiddleware {
constructor(private usersService: UsersService) {}
async use(req: Request, res: Response, next: NextFunction) {
const { userId } = req.session || {};
if (userId) {
const user = await this.usersService.findOne(userId);
req.currentUser = user;
}
next();
}
}
I attempted to just perform a general update of the interface, replacing the global declaration with the following:
interface Request {
currentUser?: User;
session?: any;
}
But that gives me another error which is Import declaration conflicts with local declaration of 'Request'.
I'm fairly certain this issue could be resolved by removing Request
from my import (and it does) but I'm not sure if that action will have any downstream effects that I'm not aware of.
Any guidance you can offer would be very much appreciated!
Another option, rather than modifying express's types directly, is to create your own interface that extends express's but adds your custom types:
The benefit here is a more explicit request type, that's still compatible with other libraries, and it works by default with extra tooling (like ts-jest) without needing extra configuration.