Ed Staub
Ed Staub

Reputation: 15690

How to use local Typescript definition file for js project in node_modules?

I'm importing a Javascript package from npm that doesn't have a Typescript definition file anywhere. I'd like to create a local definition file that I'll eventually PR to DefinitelyTyped or the project itself.

I can't figure out where/how to create and place the definition file such that it will be found locally.

I could copy it into the node_modules/the-package directory, but it'll get clobbered during otherwise safe npm operations.

From observing tsc --traceResolution, I don't see a good way to do this, unless there's some way to use types or typings that I haven't figured.

Upvotes: 0

Views: 2186

Answers (2)

Ed Staub
Ed Staub

Reputation: 15690

One of the ways I failed in this was to create a local *.d.ts file like this one-line modification of @Saravana's example:

import {Component} from 'react'

declare module 'lodash' {

  interface Lodash {
      map: Function
  }

  var _: Lodash;
  export = _;
}

This evokes the cryptic error message

Error:(3, 16) TS2665:Invalid module name in augmentation. Module 'lodash' resolves to an untyped module at 'my-project/node_modules/lodash/lodash.js', which cannot be augmented.

The error made me think that this approach must be wholly wrong, when it's really just complaining about a trivial, easy-to-fix error. When you import in a file, it converts the file into a module, and when Typescript sees a declare module inside a module, it assumes you're trying to enhance an existing definition. The fix is trivial: just move the import inside the declare block, like so:

declare module 'lodash' {

  import {Component} from 'react'

  interface Lodash {
      map: Function
  }

  var _: Lodash;
  export = _;
}

If you use an IDE with auto-import, it will break your definition files in this way every time - remember to move the import!

Upvotes: 5

Saravana
Saravana

Reputation: 40544

You can just create a local file with *.d.ts and create a module with the same name as your library.

For example, if you were using lodash, you can create typings for it by creating a d.ts file:

declare module "lodash" {

    interface Lodash {
        map: Function
    }

    var _: Lodash;
    export = _;
}

See the documentation on creating declarations.

Upvotes: 1

Related Questions