4
votes

Partially solved:

There is an old issue on github where this problem is described a bit. When you declare a module in a global scope, it rewrites the whole exported module's types. When you declare a module inside a module, it merges. Why? I have no idea

https://github.com/microsoft/TypeScript/issues/17736#issuecomment-344353174

I want to extend third party module's type by interface merging. Everything works fine, but when I comment export {}; in types.d.ts I encounter the following error:

This expression is not callable. Type 'typeof import("koa-session")' has no call signatures

Could you explain why it happens?

You can check the working code here: https://codesandbox.io/s/typescript-node-nocfq?file=/src/types.d.ts

2

2 Answers

6
votes

A similar problem has been addressed on TypeScript github. Unfortunately I am now aware of any other documentation page that would describe it.

Commenting out the export {} turns the types.d.ts file from a module into a script. From TypeScript handbook:

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).

Since the file without export statement (and without import statement) is not a module but rather a script it has no information about any modules and will indeed disregard the fact that there is an existing definition for "koa-session".

You can try this in your sandbox - adding any top-level import or export in types.d.ts (it can be completely unused) will fix the This expression is not callable error.

1
votes

You need to import the interface if you want to enhance it and do interface merging. What you're doing is rewriting it altogether.

import Session from "koa-session";
declare module "koa-session" {
  interface Session {
    user: {
      id: number;
      username: string;
    };
  }
}

Just do this and you will enhance the interface just as you want.