ts-node ignores d.ts files while tsc successfully compiles the project
Asked Answered
S

7

160

Having compiled my TypeScript project successfully, I intended to run it in VS Code's debug mode using ts-node. Problem is, ts-node can't find d.ts files I created (while tsc has no problem with it).

Project structure is:

/
    conf/
    dist/
    src/
        types/
package.json
tsconfig.json

tsconfig.json relevant entries are:

{
    "compilerOptions": {
        "target": "es2017",
        "module": "commonjs",
        // "lib": [],
        "sourceMap": true,
        "outDir": "dist",
        "rootDir": "src",
        "moduleResolution": "node",
        "baseUrl": ".",
        "paths": {
            "*": [
                "node_modules/*",
                "src/types/*"
            ]
        },
        // "rootDirs": [],
        // "typeRoots": [],
        // "types": [],
    },
    "include": [
        "src/**/*"
    ]
}

The definition file ts-node can't find is src/types/global.d.ts:

import { App } from '../App';

declare global {
    namespace NodeJS {
        interface Global {
            app: App;
        }
    }
}

So, trying to run it with ts-node I see:

TSError: ⨯ Unable to compile TypeScript:
src/boot.ts(15,59): error TS2339: Property 'app' does not exist on type 'Global'.

How to resolve it globally? I've found that /// <reference path="./types/global.d.ts" /> does the trick but I'd have to repeat it in every file using global.app.

My TypeScript version is 3.0.1

Scherer answered 31/7, 2018 at 9:55 Comment(0)
W
145

Starting with ts-node in 7.0.0, does not Load files from tsconfig.json on startup. Instead, you should specificy --files like this

ts-node --files src/boot.ts
Wilona answered 3/8, 2018 at 6:42 Comment(7)
Yes, --files does the trick. I don't know however why typeRoots doesn't. It is the way to go according to github.com/TypeStrong/ts-node#help-my-types-are-missing but I tried it and it didn't help. Anyway, --files worked but I had to find a way to wire it into VS Code's launch.json. Finally, I made a ts-node.js file in the project root that contained only: require('ts-node').register({ files: true }) and referenced it in launch.json: "runtimeArgs": [ "-r", "./ts-node.js" ]. Thanks a lot for your help!Scherer
You are my hero!Desalinate
This just saved be from hours of messing around with type declaration files, ambient variables etc. Thanks a lot @Forseti!Permeate
Everytime I come across this issue, I always find this comment again and it solves the issue right away. I'm glad this comment will always be here for me.Acetanilide
Here's an explanation of the --files option, although I still don't get why it works: github.com/TypeStrong/ts-node/issues/…Kylynn
Thanks a lot. I will still forever question why TS-Node doesn't automatically do this, it just makes life harder. In fact there should be an option to disable it and make it enabled by default, not the other way round.Ultimogeniture
In VSCode, add "env": { "TS_NODE_FILES": "true" } in launch.json to ensure ts-node correctly loads all types during debugging.Outcross
D
292

I was having a similar problem, but I could not add --files, because I run ts-node by registering the module through mocha (i.e. mocha -r ts-node/register ...).

I could solve it by adding a files and a ts-node section to tsconfig.json like this:

// tsconfig.json
{
  "ts-node": {
    "files": true
  },
  "files": [
    "src/index.ts",
    "src/global.d.ts"
  ],
  "compilerOptions":{
    //...
  }
}
Decretal answered 13/7, 2020 at 14:57 Comment(6)
this worked for me only using the "ts-node" section. Thanks.Barbwire
A great workaround for ts-node build but it completely throws off the tsc build.Bubbly
Can confirm that only adding the ts-node section makes mocha compile again without breaking tsc, thanks @Sharpiro!Fitzsimmons
files is a Boolean flag, so this solution is just as as good as setting "files": true which apparently slows down the process. I prefer to use <reference path="./global.d.ts" /> where I use theseBusinesswoman
this reply needs more creditCynic
You don't even imagine the time i spent looking for thisAbbe
W
145

Starting with ts-node in 7.0.0, does not Load files from tsconfig.json on startup. Instead, you should specificy --files like this

ts-node --files src/boot.ts
Wilona answered 3/8, 2018 at 6:42 Comment(7)
Yes, --files does the trick. I don't know however why typeRoots doesn't. It is the way to go according to github.com/TypeStrong/ts-node#help-my-types-are-missing but I tried it and it didn't help. Anyway, --files worked but I had to find a way to wire it into VS Code's launch.json. Finally, I made a ts-node.js file in the project root that contained only: require('ts-node').register({ files: true }) and referenced it in launch.json: "runtimeArgs": [ "-r", "./ts-node.js" ]. Thanks a lot for your help!Scherer
You are my hero!Desalinate
This just saved be from hours of messing around with type declaration files, ambient variables etc. Thanks a lot @Forseti!Permeate
Everytime I come across this issue, I always find this comment again and it solves the issue right away. I'm glad this comment will always be here for me.Acetanilide
Here's an explanation of the --files option, although I still don't get why it works: github.com/TypeStrong/ts-node/issues/…Kylynn
Thanks a lot. I will still forever question why TS-Node doesn't automatically do this, it just makes life harder. In fact there should be an option to disable it and make it enabled by default, not the other way round.Ultimogeniture
In VSCode, add "env": { "TS_NODE_FILES": "true" } in launch.json to ensure ts-node correctly loads all types during debugging.Outcross
E
30

TLDR

Add "ts-node": { "files": true }, in tsconfig.json for ts-node-dev to work as expected

explanation:

I was using ts-node-dev in package.json like:

"scripts": {
    "build": "tsc",
    ...
    "dev": "ts-node-dev src/index.ts"
  },

npm run build was working fine but npm run dev was failing, My type definition files are in src/types/*.

It started working fine after I added the following in my tsconfig.json

{
  "ts-node": {  "files": true }, // add this
  "compilerOptions": {
     ...
  }
}
Encephalitis answered 22/7, 2021 at 16:31 Comment(0)
I
13

I spent way to much time on this issue tried almost everything like adding to typeRoots my typings folder, creating typing folder with structure typings/module/index.d.ts but nothing worked out so now I've figured it out now what the above answer meant

With a new version of ts-node I've changed for my project's scripts:

ts-node@6: ts-node src/index.ts
ts-node@7: ts-node --files src/index

So your script will be changed to something like below

"scripts": {
    "dev": "nodemon --exec ts-node --files src/index",
  }

With the above in action your compile time increase a lot but I couldn't spend more time on this so I'm sticking to the above.

You also might like to visit https://github.com/TypeStrong/ts-node#missing-types.

Influence answered 23/10, 2019 at 9:58 Comment(4)
That link you posted is the real solution (doesn't slow down compile time): use the typeRoots compiler option.Descendible
@AndrewKoster What if I want to define one custom type globally (e.g. type Id = string;) without need to import it everywhere. It works fine with tsc if it's defined in any *.d.ts file included in compilation, but does not with ts-node. How to avoid --files option here?Intuitivism
@AndrejLeitner The example is in the link: github.com/TypeStrong/ts-node#help-my-types-are-missing It's multiple lines of code, so I can't really post it in a comment.Descendible
Yep, I've seen it, but the only one that worked for me was to pull the type definition file with /// <reference path="./types/global.d.ts" />Intuitivism
C
13

Here's How i fixed it. Add "nodemon --exec ts-node --files src/app.ts" to your dev script.

 "scripts": {
    "start": "node dist/app.js",
    "dev": "nodemon --exec ts-node --files src/app.ts",
    "build": "tsc -p",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
Challenging answered 5/3, 2020 at 6:4 Comment(1)
This worked best for me. I've also tried ts-node-dev but this kept ignoring the files defined in tsconfig.jsonBlanca
E
5

While all the other solutions are good. ts-node suggested methods (other than using --files which is last resort according to ts-node) can be found at https://www.npmjs.com/package/ts-node#missing-types.

It recommends 3 different types based on your use case and preferences.

  1. Using compilerOptions.typeRoots in tsconfig.json

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

{
  "compilerOptions": {
    "typeRoots" : ["./node_modules/@types", "./typings"]
  }
}
  1. Using paths in tsconfig.json

For module definitions, you can use paths

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "custom-module-type": ["types/custom-module-type"]
    }
  }
}
  1. Using triple slash directive

Another option is triple-slash directives. This may be helpful if you prefer not to change your compilerOptions or structure your type definitions for typeRoots. Below is an example of a triple-slash directive as a relative path within your project:

/// <reference path="./types/lib_greeter" />
import {Greeter} from "lib_greeter"
const g = new Greeter();
g.sayHello();
Exact answered 25/10, 2022 at 8:48 Comment(1)
#1 didn't work for me but #2 did 🤷‍♂️ ThanksTague
S
0

Including this code into tsconfig is enough

{
"compilerOptions": {...},
"include": [...],
"ts-node": {
  "files": true
},
}
Spinach answered 8/2, 2024 at 11:49 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.