104
votes

I can't find TypeScript definition @type/{name} for one of my installed NodeJS packages, so I attempt to write a d.ts file for it, and put the file in {project root}\typings folder. This is how I do:

// My source code: index.ts
import Helper from 'node-helper-lib';


// My definition: \typings\node-helper-lib.d.ts
declare....(something else)

declare module 'node-helper-lib' {
   class Helper { ... }
   export = Helper;
}

However, Visual Studio Code keeps yielding this error and puts red line under declare module 'node-helper-lib':

[ts] Invalid module name in augmentation. Module 'node-helper-lib' resolves to an untyped module at '{project path}\node_modules\node-helper-lib\index.js', which cannot be augmented.

Isn't it legit that because the library is untyped, so I should be allowed to add typing to it?

UPDATE:

I am using:

  • TypeScript: 2.1.4
  • Visual Studio Code: 1.9.1
  • Node JS: 6.9.4
  • Windows 10 x64
5

5 Answers

174
votes

The actual solution is given in a comment by @Paleo in @hirikarate's answer:

Imports should be declared inside the module declaration.

Example:

declare module 'node-helper-lib' {
   import * as SomeThirdParty from 'node-helper-lib';
   interface Helper {
       new(opt: SomeThirdParty.Options): SomeThirdParty.Type
   }
   export = Helper;
}
69
votes

After some tries and errors, I found that augmentation means "declaring a module in the same file with other module declaration(s)".

Therefore if we want to write a definition file for an untyped 3rd-party JavaScript library, we must have ONLY ONE declare module 'lib-name' in that file, and 'lib-name' must exactly match the library name (can be found in its package.json, "name" property).

On the other hand, if a 3rd-party library already has definition file .d.ts included, and we want to extend its functionalities, then we can put the additional definition in another file that we create. This is called augmenting.

For example:

// These module declarations are in same file, given that each of them already has their own definition file.
declare module 'events' {
   // Extended functionality
}

declare module 'querystring' {
   // Extended functionality        
}

declare module '...' { ... }

I leave my discovery here just in case somebody has same question. And please correct me if I missed something.

3
votes

I was getting that error message too. The issue for me was that I was trying to declare another module in an existing type definition file that had a module declaration in it. After I moved the new module declaration to a new file, the error went away.

0
votes

The issue for me was that I was trying to declare the module in a .ts file. I changed it to .d.ts and it all worked just fine.

-7
votes

In my case I just used following declaration in one of my types files so I was able to use all non-typescript packages:

declare module '*'