Could not find a declaration file for module

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
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!

Josh Sherman - The Man, The Myth, The Avatar

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.


If you found this article helpful, please consider buying me a coffee.