Could not find a declaration file for module

Josh Sherman
4 min read
Software Development TypeScript

I’ve been working with Typescript on a daily basis for the last year. Admittedly, I still feel pretty amateurish with it. Mostly due to the fact that I’ve mostly been working with it on an existing stack at work and minor application of it on my own side projects.

With a new side project landing on my TODO list recently, I figured it’d be a great time to really immerse myself. The stack is your typical *ERN deal, probably using Redis instead of MongoDB as the primary data store, and tsing the hell out of the whole damn thing.

And so it began, the usual anxiety of starting a brand new project from the ground up. The canvas was blank, and I had to get my research on.

Most of it’s all come together pretty well thus far, and the bigger plan here is to build myself a nice little boilerplate that I can use on future endeavors, that fits into how I build systems.

The big issue that really stopped me in my tracks last week was dealing with a couple of dependencies that lacked @types and I had to define on my own declarations for.

The error initially cropped up as a lint error in nvim (by way of ALE). It said I needed to try installing the @type for the packages and if that didn’t work, slap declare module 'package'; in the project.

Not a ton of indication as to where that should have been placed, so I dropped it into index.d.ts in the root of the problem. My linter picked up and everything was good to go.

That was, until I went to run things with ts-node. Everything actually worked fine with ts-node-dev, which I was planning to use, but I really wanted to figure out why ts-node wasn’t having it.

After a ton of research and trying a ton of different things (different file names, configuring stuff in tsconfig.json, et cetera), I was still dead in the water. Fortunately, the official Typescript documentation is pretty solid and I read up on how you’re supposed to declare modules.

The line of code to declare a module was sufficient enough, but just stuffing shit into index.d.ts (or nearly any other *.d.ts for that matter) wasn’t going to cut it.

To get ts-node to be back on Team Josh, I ended up creating a types directory, and a directory named after each dependency I was attempting to declare.

Within each directory, I added an index.d.ts and added the aforementioned declaration line. Things looked something like this:

$ tree types
└── package
    └── index.d.ts

1 directory, 1 file

$ cat types/package/index.d.ts
declare module 'package';

Hoping this would be enough for a modern version of Typescript, I tried to run my code again, and hit the same error.

Next step in the process was to configure typeRoots in my tsconfig.json file. I had read some mixed statements about this, so not entirely sure if it was the best approach, but seemed to be the best way to ensure I didn’t have to tweak the configuration every time I needed to add something new to my local types directory.

The thing with the typeRoots directive is that it’s all or nothing. It’s not like you can define your custom location and it’s loaded in additional to the defaults.

Because of this, you have to be sure to include the @type directory that’s in your node_modules as well as any additional locations:

  // everything before this line
  "typeRoots" : ["./node_modules/@types", "./types"],
  // everything after this line

Once typeRoots was updated, ts-node stopped barking at me with Could not find a declaration file for module.

As I did try a bunch of things prior, including defining the typeRoots to a directory with index.d.ts and package.d.ts, I can tell you, the trick here really is the directory structure of the declaration files.

At this point, everything was good to go. The project / boilerplate is coming together nicely and I’m excited to launch a new project here in the very near future.

If you feel like calling me out for being a total noob and/or want to take time out of your day to *splain me on a better way to go about this, comment below!

Join the Conversation

Good stuff? Want more?

Weekly emails about technology, development, and sometimes sauerkraut.

100% Fresh, Grade A Content, Never Spam.

About Josh

Husband. Father. Pug dad. Musician. Founder of Holiday API, Head of Engineering and Emoji Specialist at Mailshake, and author of the best damn Lorem Ipsum Library for PHP.

Currently Reading

Parasie Eve

Previous Reads

Buy Me a Coffee Become a Sponsor

Related Articles