Closed shusson closed 6 years ago
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.
Ok @blakeembrey , but then ts-node
should have worked with with the --files
flag right?
Yes, probably. In any case this is based on the TypeScript compiler API, so I’d need a full reproduction if you believe it’s a bug.
Sorry my mistake. I couldn't reproduce with a simple setup. Looks like it's to do with our own structure.
I'm running into this problem after upgrading to ts-node 7.x and typescript 3.x. Everything was working with ts-node 6.x and typescript 2.7.x.
Did you ever figure out your issue?
Note: my tsconfig.json doesn't have any include/excludes and npx tsc
works correctly. The problem is specific to when running npx ts-node myscript.ts
.
Note2: This is a common ask in the issues here, but unlike most of them, me and the OP are following the instructions in the README and adding "typeRoots": [ "./typings" ]
where our custom module definitions are defined. However, this doesn't appear to actually work.
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.
@MicahZoltu This is in the README. Both styles are supported. Please read the section about types to understand why it’s not working for you.
FWIW, the first method you describe is not supported by TypeScript. It’s working accidentally with tsc
because your configuration includes it, not because TypeScript looks it up. This is in the README. Feel free to share your project/structure if you feel this is incorrect.
@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. Exampletsconfig.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.
Feel free to submit a PR for the documentation change. I’m on mobile so unable to link to the section correctly, but that’s the correct section. It works with TypeScript by default because, when you don’t specify the files/includes, it would be traversing your entire directory for TypeScript files. I’m not sure if the expectation here otherwise, since tsc
appears to be compiling everything right?
Yes, tsc
is compiling everything when run from the directory containing the tsconfig.json
. IIUC, you are saying that this means that tsc will naturally find any types you have in any directory that is being compiled, and normally you would only need to include typeRoots
if you want to pull type data from a directory that is outside the directory being compiled. However, since ts-node doesn't compile anything by default other than the referenced file (and things that file references) it won't find any type files automatically unless they are located on the import
lookup path (such as in node_modules
).
Pretty much, yes. To TypeScript, the global declarations can be understood any time (the structure is usually more import with the module style declarations). But yeah, since we aren’t globing the entire directory it needs to follow the structure TypeScript supports. Fortunately this is TypeScript native suppport, so fixing for ts-node
does not change behaviour on the compiler.
I’d love to see the documentation PR, it’s definitely an improvement over what I originally wrote!
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
@blakeembrey did something change here? This does not work for us
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",
We have to configure all modules in the paths instead
"paths": { "module_name": ["types/module_name"] },
Odd as it seems, this worked for me. Thanks @andidev. Note for others that both of the following structures work:
types/
├── module_name
│ └── index.d.ts
└── module_name.d.ts
If you have a config like this:
And a directory structure like this:
ts-node will not be able to find the module defs in index.d.ts
ts-node will work if you have something like:
Typescript will work with either setup.