145

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

Forseti
  • 2,587
  • 6
  • 21
  • 32

6 Answers6

260

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":{
    //...
  }
}
double-beep
  • 5,031
  • 17
  • 33
  • 41
djlauk
  • 3,359
  • 1
  • 12
  • 12
139

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
KyleMit
  • 30,350
  • 66
  • 462
  • 664
欧阳斌
  • 2,231
  • 1
  • 8
  • 8
  • 26
    Yes, `--files` does the trick. I don't know however why `typeRoots` doesn't. It is the way to go according to https://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! – Forseti Aug 03 '18 at 19:58
  • You are my hero! – Huan Jun 01 '19 at 15:46
  • 3
    This just saved be from hours of messing around with type declaration files, ambient variables etc. Thanks a lot @Forseti! – Folusho Oladipo Oct 14 '19 at 22:11
  • 4
    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. – 55 Cancri Nov 16 '20 at 00:03
  • 1
    Here's an explanation of the `--files` option, although I still don't get why it works: https://github.com/TypeStrong/ts-node/issues/1132#issuecomment-714582153 – bendytree Apr 13 '21 at 20:50
  • 1
    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. – Epic Speedy Jul 05 '21 at 17:02
27

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": {
     ...
  }
}
Sahith Vibudhi
  • 4,935
  • 2
  • 32
  • 34
12

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"
  },
Basanta Kc
  • 245
  • 4
  • 5
11

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.

Quill
  • 2,729
  • 1
  • 33
  • 44
Black Mamba
  • 13,632
  • 6
  • 82
  • 105
  • 3
    That link you posted is the real solution (doesn't slow down compile time): use the `typeRoots` compiler option. – Andrew Koster Dec 04 '20 at 04:10
  • @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? – Andrej Leitner Apr 20 '22 at 15:12
  • @AndrejLeitner The example is in the link: https://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. – Andrew Koster Apr 29 '22 at 22:43
  • Yep, I've seen it, but the only one that worked for me was to pull the type definition file with `/// ` – Andrej Leitner May 01 '22 at 19:32
4

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();
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Ferido07
  • 41
  • 2