16

My use case: request's RequestResponse type definition is missing the body property and looks like this:

declare namespace request {

    // ...

    export interface RequestResponse extends http.IncomingMessage {
        request: Options;
    }

    // ...

}
declare var request: request.RequestAPI<request.Request, request.CoreOptions, request.RequiredUriUrl>;
export = request;

I'm trying to fix it by creating a request-fix.d.ts file with something like this:

import * as http from 'http';
declare namespace request {
    export interface RequestResponse extends http.IncomingMessage {
        body: any;
    }
}

But it has no effect. My end goal is that in my app.ts, I can do this:

import * as rp from 'request-promise';
import { RequestResponse } from 'request';

let response = rp.get(url);

response.statusCode; // works
response.body; // doesn't compile

Of course I could just contribute to DefinitelyTyped :) But this question is about to augment the RequestResponse interface.

6
  • 1. missing export for RequestResponse in request-fix.d.ts 2. is request-fix.d.ts added to files in tsconfig.json? Commented Feb 16, 2017 at 0:22
  • The .d.ts file is not producing any compile time errors even when I put nonsense there. In my tsconfig.json: "files": ["app.ts", "request-fix.d.ts" ]. Tried adding /// <reference ...> to my app.ts, no difference. Commented Feb 16, 2017 at 0:36
  • Oh skipLibCheck was true. That moves me forward, at least I can see some more errors.. Commented Feb 16, 2017 at 0:38
  • Now the .d.ts certainly compiles but the .body property is still not recognized by the compiler. Commented Feb 16, 2017 at 0:42
  • Are you trying to overwrite their RequestResponse type declaration file with your own version? Commented Feb 16, 2017 at 1:12

2 Answers 2

24

Here is the combination that works in request-fix.d.ts:

import * as http from 'http';

declare module 'request' {
    export interface RequestResponse extends http.IncomingMessage {
        body: any;
    }
}

To augment existing module, declare module must be used instead of declare namespace, and it must appear in the module scope somewhere among the compiled sources.

That is, request-fix.d.ts must have some import at top level to turn it into a module, as you did with import * as http from 'http' in your code. If declare module appears in the non-module scope, (as I did with the first attempt at the answer), it just declares separate, unrelated module as described here.

Sign up to request clarification or add additional context in comments.

3 Comments

It doesn't work for me. I've created this small repo to demonstrate the issue: github.com/borekb/ts-augmentation-demo
The import must be at the top level, I've updated the GitHub demo with working solution: github.com/borekb/ts-augmentation-demo. (If you update your code, I'll mark it as a the answer. Thanks for your help!)
Important note: declare module request is NOT the same as declare module "request". Had me puzzled for some time. (with the quotes, it tries to resolve the module to existing module matches; without, it assumes you're declaring a whole new module/namespace)
4

@artem is right, +1, just wanted to add that you shouldn't forget about the namespaces.

For example, this is how you add a className prop to the CardTitle component from material-ui:

declare module "material-ui" {
    namespace __MaterialUI {
        namespace Card {
            export interface CardTitleProps {
                className?: string;
            }
        }
    }
}

The explaination is simple.. Modules and namespaces only exist in runtime and are merged automatically.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.