0

I have some express module augmentations. My intention is to be able to do:

request.message('Hello').status(400).json({});

The status and json functions are part of the express Response object. These functions return the Response object they were called on to allow chaining (a.k.a a fluent API).

I wish to add my own message function to do much the same. My augmentation looks like so:

import { SomeType } from '...';

declare global {
    namespace Express {
        interface Response {
            // This works.  
            getSomeType(): SomeType;

            // This does not.  Typescript thinks the object returned here has ONLY the getSomeType/message functions on it
            message(str: string): Response; 
        }
    }

I've tried variations of

message(str: string): Express.Response

And

message(str: string): Response & Express.Response

This made no difference. As before: Typescript thinks the object returned here has ONLY the getSomeType/message functions on it

Richard Walton
  • 4,789
  • 3
  • 38
  • 49
  • 1
    Express isn't a global. You are therefore doing it wrong – Aluan Haddad Mar 18 '19 at 19:06
  • @AluanHaddad I'm not so sure. It's a bit of black magic to be sure, but something about the `imports` I need requires this. After much googling I found the reason for this (Not that I can remember what it was). If I change to `declare module 'express' { .... }` none of my augmentations work! – Richard Walton Mar 18 '19 at 19:13

2 Answers2

2

Maybe if you write like this it will be work:

import { SomeType } from '...';

declare namespace Express {
  export interface Response {
      getSomeType(): SomeType;
      message(str: string): Response; 
  }
}

Here was similar question

Alex
  • 1,373
  • 8
  • 15
  • Alas, doing this breaks all my augmentations for express. It's interesting reading the different answers for that thread (I've seen it before)...you see that they all have comments saying "X didn't work for me, I had to do Y". The only thing (so far) to work for me is what I posted... at least until this issue :) – Richard Walton Mar 18 '19 at 19:30
  • I have the following (relating to express): `"@types/express": "^4.16.1",` & `"@types/express-session": "^1.15.12",` Running typescript `3.3.3333` – Richard Walton Mar 18 '19 at 19:44
  • One more question: is this declaration in `d.ts` file or `ts` file? – Alex Mar 18 '19 at 19:51
  • It's in a file named `express.d.ts` – Richard Walton Mar 18 '19 at 20:05
0

Ok, found the solution. I needed to import express into my type augmentation, and make my augmentation return express.Response:

import { SomeType } from '...';
import express from 'express';

declare global {
    namespace Express {
        interface Response { 
        getSomeType(): SomeType;
        message(str: string): express.Response; 
    }
} 
Richard Walton
  • 4,789
  • 3
  • 38
  • 49