dkimot
dkimot

Reputation: 2289

How to extend @types/express request interface?

While people have asked similar questions, none of those answers are solving my problem. I'm in TypeScript 2.9.2 and I'm trying to add a context object to the Express Request object. I want to do it in a .d.ts file.

What I currently have is this: express.d.ts

declare namespace Express {
    interface Request {
        context: any;
    }
}

However, it won't compile because `Property 'context' does not exist on type 'Request'.

In my other files, Webstorm claims the Request type is getting imported from the proper file.

I was under the impression that I could take advantage of declaration merging and not have to import or export a type definition.

Is this incorrect?

Upvotes: 6

Views: 5633

Answers (2)

laktak
laktak

Reputation: 60103

With the current version of TypeScript you do not need to create a .d.ts file.

import express from "express";

export type MyRequest = express.Request & {
  context?: any;
};

Then use it in place of the regular request object:

app.use(function (req: MyRequest, res: Response, next: NextFunction) {
  req.context = {};
  next();
}

Upvotes: 0

Cerberus
Cerberus

Reputation: 10352

Just a small modification for this to work:

declare namespace Express {
    export interface Request {
        context: any;
    }
}

When we define an interface (or, in fact, anything from constants to classes) inside namespace, it's visible by default only for the members of the same namespace, as stated in the handbook. By adding export we let TypeScript know that this interface must be used by the outside code, and it will be correctly merged into the existing declaration.

This is not a true export, as it would be from the module (on the top level), since the namespace itself is declared, not exported. So you just import it from module as usual:

import * as express from 'express';

Upvotes: 8

Related Questions