Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend Express Request object using Typescript

You want to create a custom definition, and use a feature in Typescript called Declaration Merging. This is commonly used, e.g. in method-override.

Create a file custom.d.ts and make sure to include it in your tsconfig.json's files-section if any. The contents can look as follows:

declare namespace Express {
   export interface Request {
      tenant?: string
   }
}

This will allow you to, at any point in your code, use something like this:

router.use((req, res, next) => {
    req.tenant = 'tenant-X'
    next()
})

router.get('/whichTenant', (req, res) => {
    res.status(200).send('This is your tenant: '+req.tenant)
})

As suggested by the comments in the index.d.ts, you simply declare to the global Express namespace any new members. Example:

declare global {
  namespace Express {
    interface Request {
      context: Context
    }
  }
}

Full Example:

import * as express from 'express';

export class Context {
  constructor(public someContextVariable) {
  }

  log(message: string) {
    console.log(this.someContextVariable, { message });
  }
}

declare global {
  namespace Express {
    interface Request {
      context: Context
    }
  }
}

const app = express();

app.use((req, res, next) => {
  req.context = new Context(req.url);
  next();
});

app.use((req, res, next) => {
  req.context.log('about to return')
  res.send('hello world world');
});

app.listen(3000, () => console.log('Example app listening on port 3000!'))

Extending global namespaces is covered more at my GitBook.


For newer versions of express, you need to augment the express-serve-static-core module.

This is needed because now the Express object comes from there: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8fb0e959c2c7529b5fa4793a44b41b797ae671b9/types/express/index.d.ts#L19

Basically, use the following:

declare module 'express-serve-static-core' {
  interface Request {
    myField?: string
  }
  interface Response {
    myField?: string
  }
}

After trying 8 or so answers and not having a success. I finally managed to get it working with jd291's comment pointing to 3mards repo.

Create a file in the base called types/express/index.d.ts. And in it write:

declare namespace Express {
    interface Request {
        yourProperty: <YourType>;
    }
}

and include it in tsconfig.json with:

{
    "compilerOptions": {
        "typeRoots": ["./types"]
    }
}

Then yourProperty should be accessible under every request:

import express from 'express';

const app = express();

app.get('*', (req, res) => {
    req.yourProperty = 
});

The accepted answer (as the others) does not works for me but

declare module 'express' {
    interface Request {
        myProperty: string;
    }
}

did. Hope that will help someone.


None of the offered solutions worked for me. I ended up simply extending the Request interface:

import {Request} from 'express';

export interface RequestCustom extends Request
{
    property: string;
}

Then to use it:

import {NextFunction, Response} from 'express';
import {RequestCustom} from 'RequestCustom';

someMiddleware(req: RequestCustom, res: Response, next: NextFunction): void
{
    req.property = '';
}

Edit: Depending on your tsconfig, you may need to do it this way instead:

someMiddleware(expressRequest: Request, res: Response, next: NextFunction): void
{
    const req = expressRequest as RequestCustom;
    req.property = '';
}