CodePark/ questions / TypeScript on the server
START PRACTICINGPRACTICE
Backend question · TypeScript › TypeScript on the server

Your auth middleware sets req.user. How do you make req.user type-check in every Express handler without casting?

// src/types/express.d.ts
import type { AuthUser } from "../auth/types";

declare global {
  namespace Express {
    interface Request {
      user?: AuthUser;
    }
  }
}

Add user to the global Express.Request interface with declaration merging. Express's type definitions make its Request type extend this global interface. Interfaces with the same name merge: TypeScript combines their fields into one. So you can add your own fields to that interface from a declaration file, and every handler and middleware sees them.

Two setup rules:

  • The file must be a module, so that declare global is allowed. Here the import makes it a module. Without an import, add export {}.
  • The tsconfig must include the file.

Make the property optional, because the type cannot know whether the auth middleware ran on a given route. Handlers should check req.user, or rely on a guard that throws. Avoid (req as any).user in each handler. It hides typos, and it drifts away from what the middleware really sets.

  • Express's Request extends the global Express.Request interface.
  • Declaration merging adds fields through declare global.
  • The file must be a module and included by tsconfig.
  • Keep user optional, and narrow or guard before using it.