6

When extending the Express.Request interface in TypeScript I ran into this problem that I want to use an external library definition, but I can't import the external library as it results in error ->

Error:(4, 28) TS1147: Import declarations in an internal module cannot reference an external module.

Edit: It is a .d.ts file

/// <reference path="../typings/express/express.d.ts" />

declare module Express {
    import bunyan = require('bunyan'); <-- results in error
    export interface Request {
        _id: string; <-- this works
        log: bunyan.Logger; <-- Here I want to define that it is bunyan.Logger instance;
    }
}

Trying to reference the bunyan.d.ts (https://github.com/borisyankov/DefinitelyTyped/blob/master/bunyan/bunyan.d.ts) Also results in a problem, as the bunyan module is exported as string

declare module "bunyan" {
...
}

As such trying to use it from reference results in not found.

/// <reference path="../typings/express/express.d.ts" />
/// <reference path="../typings/bunyan/bunyan.d.ts" />

declare module Express {
    export interface Request {
        _id: string;
        log: bunyan.Logger; <- Error:(8, 18) TS2304: Cannot find name 'bunyan'.
    }
}

tl;dr; How to extend interface definition with external module definitions.

5
  • Why declare in declare module Express? Commented Apr 8, 2015 at 14:03
  • @Tarh Error:(4, 1) TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. Commented Apr 8, 2015 at 14:04
  • OK. The require misled me, I believed it was a .ts file. Commented Apr 8, 2015 at 14:10
  • A suggestion: if a file .d.ts exists for the external module bunyan, you can reference it with /// <reference ... and then use it to type Request.log. Commented Apr 8, 2015 at 14:13
  • External modules are not namespaces. Try to use Logger instead of bunyan.Logger. If it still not works, then you can try to upgrade to typescript 1.5-alpha and to use the external module import syntax. Or edit the .d.ts file and remove the quotes in declare module "bunyan" => declare module bunyan. Without quotes, bunyan becomes a namespace and bunyan.Logger becomes available. Commented Apr 8, 2015 at 15:31

2 Answers 2

3

I don't think you can add to an existing interface when a require is necessary, but you can extend the existing interface using the extends keyword.

Move your import statement outside your module, export your module, and extend the existing interface:

import bunyan = require('bunyan');
import express = require('express');

export declare module ExtendedExpress {
    export interface Request extends express.Express.Request {
        _id: string;
        log: bunyan.Logger;
    }
}

Then you have to import this module where you want to use it.

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

3 Comments

Adding an import outside the declare function causes all the extensions being lost. (The fail is as if not referenced at all) Error:(71, 9) TS2339: Property '_id' does not exist on type 'Request'.
Yes, I can extend this way creating a new interface with a different name. Not what I want though -> The express module has internal RequestHandler interface that uses the Request interface. By creating a new interface I would have to import and define on every route handler that the parameters are of the new interface not the old - very cumbersome. Whereas extending the old interface gives me this information automatically.
@DeadAlready if you really want to do what you want, then I think you have to edit the original express.d.ts directly. There's a few guys who frequent the typescript tag and they're more knowledge than me on this so they'll probably be able to give a more definitive answer.
1

The referencing of internal and external modules will be improved in v1.5 which is currently in an alpha release (http://blogs.msdn.com/b/typescript/archive/2015/03/27/announcing-typescript-1-5-alpha.aspx).

In the meantime you can import in your bunyan module via:

var bunyan = require('bunyan');

1 Comment

Error:(4, 16) TS1039: Initializers are not allowed in ambient contexts.

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.