ts-node: Cannot find module defs using typeRoots

If you have a config like this:

{
  "compilerOptions": {
    ...
    "typeRoots" : ["./typings"]
  }

And a directory structure like this:

-- tsconfig.json
  -- typings
    -- index.d.ts

ts-node will not be able to find the module defs in index.d.ts

ts-node will work if you have something like:

-- tsconfig.json
  -- typings
    -- <library_name>
      -- index.d.ts

Typescript will work with either setup.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 15 (11 by maintainers)

Most upvoted comments

@blakeembrey Can you be more specific? I have read the README several times over and the only workaround I have been able to find is the one @shusson mentioned, which is to break my module declarations out into index.d.ts files in folders named after the module and add a typeRoots section.

My tsconfig.json does not have a reference to files, include or exclude, in fact it is quite small/simple:

{
	"compilerOptions": {
		"module": "commonjs",
		"target": "es2015",
		"noImplicitAny": true,
		"allowJs": false,
		"noEmit": true,
		"strict": true,
		"lib": [ "es2018", ],
	}
}

The readme says:

TypeScript Node does not use files, include or exclude, by default.

Great, I am not using any of those compiler options so that doesn’t apply to me.

It then goes on to say:

For global definitions, you can use typeRoots:

Great, I have some global module definitions so I can put them into typeRoots.

Unfortunately, this is where things fall apart, putting my module definitions into a file in typeRoots does not work as I expect.

I somewhat suspect (after reading the readme 3 more times while drafting this response) that the magic is in this statement:

A types package is a folder with a file called index.d.ts or a folder with a package.json that has a types field. – TypeScript Handbook

If I’m interpreting that correctly, when combined with your insistence that “the answer is in the README”, it is saying that the typeRoots mentioned previously only works if the types are setup as type package folders within the typeRoots directory?


Since I don’t want to be yet another person who complains but offers no solutions, I would recommend rewording that section to be more clear. Looking through GitHub issues, there are about a dozen issues with people struggling with this same problem, which suggests to me that the way it is currently worded is not immediately apparent to the casual ts-node user.

Perhaps something like:

For global definitions, you can use the typeRoots compiler option. This requires that your type definitions be structured as type packages (not loose TypeScript definition files). More details on how this works can be found in the TypeScript Handbook. Example tsconfig.json:

{
  "compilerOptions": {
    "typeRoots" : ["./node_modules/@types", "./typings"]
  }
}

Example project structure:

<projcet_root>/
-- tsconfig.json
-- typings/
  -- <module_name>/
    -- index.d.ts

Example module declaration file:

declare module '<module_name>' {
    // module definitions go here
}

It’s working accidentally with tsc because your configuration includes it, not because TypeScript looks it up.

What part of my configuration is causing this to happen? I have included my tsconfig.json, and in fact tsc works without the typeRoots section at all. Is there some other config you are referring to besides tsconfig.json? I’m just running tsc in the directory with the tsconfig.json file and it is successfully compiling, I am not passing in any additional compiler options or providing any files.

@blakeembrey did something change here? This does not work for us image

We have to configure all modules in the paths instead

"paths": {
    "src/*": ["src/*"],
    "module_name": ["types/module_name"]
},

we use

"ts-node": "10.9.1",
"typescript": "4.8.2",

Ok @blakeembrey , but then ts-node should have worked with with the --files flag right?

PR to edit documentation to hopefully reduce the number of people that show up here in the issues with the same problem: https://github.com/TypeStrong/ts-node/pull/698

See the README. This is not the correct structure.

Can you provide some details on why this is not the correct structure? It is accepted by TypeScript compiler without problem. There are two supported (as far as I know) ways to have modules. One is by creating some .d.ts file in typeRoots directory (e.g., my.d.ts) with one or more declare module 'whatever' { ... } blocks in it, and another is to create a a folder named myModule with a file named index.d.ts in it that contains declare module 'myModule' { ... }. Both methods appear to be fully supported by the compiler, but only the latter method appears to be supported by ts-node.

At the least, the README should be updated to mention that you cannot use the former style, and ideally a brief blurb or link to the reasoning would be appreciated.

See the README. This is not the correct structure. It most likely works with TypeScript because you have it explicitly or explicitly in your includes.