2

I want to modify the prototype of the nodejs module module.

@types/node has an interface defined for this (NodeModule) but don't has anything when I import the module, so I have to require it.

import * as Module from "module"; // Error
var Module = require("module"); // Ok

The problem is that Module don't has any definition. Is returned as any.

I have this

export interface CustomNodeModule extends NodeModule {
    __thingy:()=>void;
}

Module.prototype.__thingy = function() {
    // things!
}

I have to create my own CustomNodeModule interface, but, how can I modify the Module prototype and also those functions know that they are part of a CustomNodeModule instance?

2 Answers 2

2

In some global file (one with no imports/exports), add the following:

declare module "module" {
    export = Module;

    var Module: ModuleConstructor;

    interface ModuleConstructor {
        new (id: any, parent: any): NodeModule;
        readonly prototype: NodeModule;

        Module: typeof Module;
        globalPaths: string[];
        /** @deprecated */
        requireRepl(...args: string[]): any;
        runMain(): void;
        wrap(script: any): any;
        wrapper: string[];
    }
}

Note: sending a pull request to DefinitelyTyped with this would probably be accepted.

Then, in the module where you actually tack a new property on, you can write:

import m = require("module");

// This is a *global augmentation*.
// It adds to declarations in the global scope.
declare global {
    interface NodeModule {
        __thingy: () => void;
    }
}

m.prototype.__thingy = function() {
    // ...
};
Sign up to request clarification or add additional context in comments.

4 Comments

So I need to create my own module. Thank you! +1 for the This is a *global augmentation*.. Was important here.
Just noticed that the problem still persists. __thingy() function still don't knows that this is a NodeModule.
You can add a this type annotation in the type of __thingy (i.e. __thingy: (this: NodeModule) => void) TypeScript should be able to infer the type of this in the function body itself afterwards. Read more here, and turn on --noImplicitThis to be safer.
You're welcome! For the record, you shouldn't even need to add the annotation on the function expression, but it's definitely a style preference thing.
2

Since TypeScript interfaces are open ended you shouldn't have to need to create another interface, you can just extend the existing one with your method.

export interface NodeModule {
    __thingy:()=>void;
}

6 Comments

Oh, that's true. Now I remember that I've read about that some months ago when I started with TypeScript :-/ +1 for that
Now the important question, how can I overwrite Module prototype so they know that the this instance is a NodeModule?
Oh yeah, now I remember why I've done this. When I don't do extend the interface, NodeModule is not mixed (maybe because comes from a @types, I don't know), so I created a custom interface. Was not a big deal. Check i.imgur.com/VtQHOyb.png and i.imgur.com/ojd2APj.png
@JorgeFuentesGonzález if you have a better solution for your particular case please post it and mark it as the correct answer, so people will know. :)
I still don't have a solution. I was just telling why I created an interface extending NodeModules instead of directly adding parameters to it. Going to ask in GitHub as the question here don't has much visits. Thank you for your time :-)
|

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.