Extending express.js Request in TypeScript
node.js

Extending express.js Request in TypeScript

Marcell Simon
Marcell Simon

When you start working with express in TypeScript it is inevitable to stumble into the problem, that you want to add data to the Request object in one of your middlewares. Mostly I add the User object to it after succesful authentication.

First it seemed to be easy, but after I tried every stackoverflow solution I became furious.

Finally after merging several solutions I found the one that worked for me with VSCode also linting the right class.

tsconfig.json

{
  "compilerOptions": {
    ...
    "typeRoots": ["./src/typings/", "./node_modules/@types"]
  }, 
  "files": [
    "./src/typings/express/index.d.ts"
  ],
  "include": [
    "src/**/*"
  ]
}

src/typings/express/index.d.ts

import User from "../../db/models/User"

declare global {
  namespace Express {
    interface Request {
      user: User
    }
  }
}

isAuthenticated.ts

export default async function isAuthenticated(req: Request, res: Response, next: NextFunction) {
  const token = req.headers.token as string
  if(!token) {
    return res.status(401).send("Missing token")
  }

  let authenticationToken = await AuthenticationToken.findOne({
    id: token
  })
  
  if(authenticationToken === null) {
    return res.status(401).send("Invalid token")
  }
  
  if(moment(authenticationToken.validTo).isBefore(moment())) {
    return res.status(401).send("Invalid token")
  }

  const user = await User.findOne({
    id: authenticationToken.userId
  })

  req.user = user

  next()
}

Photo by Streetwindy Bui from Pexels