Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom typings not working with ts-node 8.0.2 #782

Closed
p-kuen opened this issue Feb 13, 2019 · 42 comments
Closed

Custom typings not working with ts-node 8.0.2 #782

p-kuen opened this issue Feb 13, 2019 · 42 comments

Comments

@p-kuen
Copy link

p-kuen commented Feb 13, 2019

After updating to ts-node version 8.0.2 the custom typings (currently placed in ./types) don't work anymore.
When I am changing the version to 8.0.1 the typings are working fine.

Typescript version: 3.3.3

Current tsconfig.json:

{
  "compilerOptions": {
    "sourceMap": true, // allow sourcemap support
    "strictNullChecks": true, // enable strict null checks as a best practice
    "strict": true,
    "target": "esnext", // specify ECMAScript target version
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "declaration": false,
    "typeRoots": ["./@types"],
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "./build"
  },
  "include": ["./src/", "./types"],
  "exclude": ["node_modules", ".logs", "upload"]
}

Error Message:

uncaughtException: ⨯ Unable to compile TypeScript:
src/import/law.ts(2,28): error TS7016: Could not find a declaration file for module 'csv-string'. '/home/patrick/dev/bodner-api/node_modules/csv-string/index.js' implicitly has an 'any' type.
  Try `npm install @types/csv-string` if it exists or add a new declaration (.d.ts) file containing `declare module 'csv-string';`

TSError: ⨯ Unable to compile TypeScript:
src/import/law.ts(2,28): error TS7016: Could not find a declaration file for module 'csv-string'. '/home/patrick/dev/bodner-api/node_modules/csv-string/index.js' implicitly has an 'any' type.
  Try `npm install @types/csv-string` if it exists or add a new declaration (.d.ts) file containing `declare module 'csv-string';`

    at createTSError (/home/patrick/dev/bodner-api/node_modules/ts-node/src/index.ts:228:12)
    at getOutput (/home/patrick/dev/bodner-api/node_modules/ts-node/src/index.ts:334:40)
    at Object.compile (/home/patrick/dev/bodner-api/node_modules/ts-node/src/index.ts:367:11)
    at Module.m._compile (/home/patrick/dev/bodner-api/node_modules/ts-node/src/index.ts:413:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Object.require.extensions.(anonymous function) [as .ts] (/home/patrick/dev/bodner-api/node_modules/ts-node/src/index.ts:416:12)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
@blakeembrey
Copy link
Member

This is expected behavior, have you read https://github.com/TypeStrong/ts-node#help-my-types-are-missing?

@kgaregin
Copy link

kgaregin commented Feb 18, 2019

👍 for broken custom typings.
node-ts 8.0.1 have no such problem, also tsc doesn't see any problems with TS 3.3.3

My case:

start script at package.json:

"scripts": {
    "server-dev": "ts-node --project src/server/tsconfig.json src/server/server.ts"
}

project structure:

<project_root>/
-- tsconfig.json
--src/
    server.config.ts
    --server/
        -- typings/
            -- hapi/
                -- index.d.ts
        server.ts
        tsconfig.json

contents of typings/hapi/index.d.ts:

import {ServerOptionsCache} from 'hapi';

declare module 'hapi' {
    interface ApplicationState {
        cache?: ServerOptionsCache;
    }
}

base tsconfig.json:

{
  "compilerOptions": {
    "lib": [
      "dom",
      "es6",
      "dom.iterable",
      "scripthost",
      "es2017"
    ],
    "jsx": "react",
    "noEmit": true,
    "noErrorTruncation": true,
    "skipLibCheck": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "pretty": true
  }
}

src/server/tsconfig.json:

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "module": "commonjs",
    "experimentalDecorators": true,
    "target": "ES5",
    "moduleResolution": "node",
    "sourceMap": true,
    "typeRoots": [
      "../../node_modules/@types",
      "./typings/hapi"
    ]
  },
  "include": [
    "../server",
    "../server.config.ts"
  ],
  "exclude": [
    "../client"
  ]
}

error stacktrace:

> huckleberry-ogre@2.0.0 server-dev D:\IdeaProjects\huckleberry-ogre
> ts-node --project src/server/tsconfig.json src/server/server.ts

Mon, 18 Feb 2019 10:54:05 GMT sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators at node_modules\sequelize\lib\sequelize.js:242:13

D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:228
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
src/server.config.ts(59,24): error TS2339: Property 'cache' does not exist on type 'ApplicationState'.

    at createTSError (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:228:12)
    at getOutput (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:334:40)
    at Object.compile (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:367:11)
    at Module.m._compile (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:413:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Object.require.extensions.(anonymous function) [as .ts] (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:416:12)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (D:\IdeaProjects\huckleberry-ogre\src\server\server.ts:8:1)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Module.m._compile (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:413:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Object.require.extensions.(anonymous function) [as .ts] (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\index.ts:416:12)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at Object.<anonymous> (D:\IdeaProjects\huckleberry-ogre\node_modules\ts-node\src\bin.ts:151:12)
    at Module._compile (internal/modules/cjs/loader.js:689:30)

@blakeembrey did try your approach, still having this issue with 8.0.2 😞

@blakeembrey
Copy link
Member

@kgaregin Your typeRoots should be only "./typings". Does that work now?

@3mard
Copy link
Contributor

3mard commented Feb 20, 2019

@kgaregin here is an example of extending express request https://github.com/3mard/ts-node-example

@p-kuen
Copy link
Author

p-kuen commented Mar 12, 2019

Updating tsconfig.json like this works for me now:

{
  "compilerOptions": {
    "sourceMap": true, // allow sourcemap support
    "strictNullChecks": true, // enable strict null checks as a best practice
    "strict": true,
    "target": "esnext", // specify ECMAScript target version
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "declaration": false,
    "typeRoots": ["./node_modules/@types", "./typings"],
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "outDir": "./build"
  },
  "include": ["./src/", "./typings"],
  "exclude": ["node_modules", ".logs", "upload"]
}

Folder structure is as described in https://github.com/TypeStrong/ts-node#help-my-types-are-missing.

@p-kuen p-kuen closed this as completed Mar 12, 2019
@kgaregin
Copy link

looks like it works again with ts-node@8.0.3 version (like this "typeRoots": ["./node_modules/@types", "./typings"])

@VictorioBerra
Copy link

I am having this exact same issue and nothing mentioned here works. I am on 8.3.0

@VictorioBerra
Copy link

VictorioBerra commented May 28, 2019

Also, that link about "help my types are missing" mentioned shows this structure:

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

But im not sure what to put for <module_name> when my module name is @ABC/module123. You cannot have slashes in a folder name.

@VictorioBerra
Copy link

/// <reference types="./types/untyped_js_lib" /> was the solution that finally worked for me.

@anthwinter
Copy link

anthwinter commented Jul 20, 2019

@VictorioBerra possibly:

<project_root>/
-- tsconfig.json
-- typings/
  -- @ABC/
    --modules123/
       -- index.d.ts

The above solution worked for me, having this exact folder structure with my global types in a 'typings' folder

@zerubeus
Copy link

zerubeus commented Nov 8, 2019

When using with ts-node you have to add --files flag

ts-node --files src/server.ts 

@samuraime
Copy link

samuraime commented Nov 15, 2019

folder structure

<project_root>/
-- tsconfig.json
-- src/
  -- types
    -- global
       -- index.d.ts

tsconfig.json

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

This works for me. and index.d.ts's name must be index.

@mlaopane
Copy link

mlaopane commented Nov 16, 2019

In my case, I was trying to use an express.d.ts file but following 3dmard's example (https://github.com/3mard/ts-node-example) solved the issue.

Here is an example for Express.Request

  1. Create a file located at typings/express/index.d.ts :
declare namespace Express {
    export interface Request {
        token: string;
    }
}
  1. Add the typeRoots entry in the tsconfig.json, with the right order :
{
    "compilerOptions": {
        "typeRoots": ["./typings", "./node_modules/@types"],
    }
}

@evenfrost
Copy link

@zerubeus's comment helped me and fixed missing declarations error, thank you. But what exactly are --files flag? Readme doesn't actually help, or it's just me who doesn't get it.

Load files from tsconfig.json on startup

Which files does it load? I don't have files property in my tsconfig.json, so how is it referred to each other? I have typeRoots in my tsconfig.json, but ts-node doesn't seem to tolerate it at all until you provide --files flag. Then why are typeRoots referenced as solution to missing types in https://github.com/TypeStrong/ts-node#help-my-types-are-missing? It's just seems unlogical.

@ledenis
Copy link
Contributor

ledenis commented Dec 7, 2019

@evenfrost It seems that omitting --files make the compiler ignore files and include of tsconfig.json

https://github.com/TypeStrong/ts-node/blob/master/src/index.ts#L644

@blakeembrey
Copy link
Member

Then why are typeRoots referenced as solution to missing types in https://github.com/TypeStrong/ts-node#help-my-types-are-missing? It's just seems unlogical.

Your typeRoots probably aren't configured properly if it doesn't work.

Feel free to submit a PR improving documentation.

@evenfrost
Copy link

@blakeembrey I've tried both with and without typeRoots at all and got the same result.

Feel free to submit a PR improving documentation.

To submit a PR, one should have an understanding about what they're doing. I just don't get what this option does, that's why I'm asking here.

@blakeembrey
Copy link
Member

@evenfrost You’d need to share a reproduction for help. The documentation in the README works when followed correctly, but I know there’s nuances to how TypeScript works.

@toancaro
Copy link

toancaro commented Mar 19, 2020

@evenfrost I found this from TypeScript official docs. I think it could answer your question.

If the "files" and "include" are both left unspecified, the compiler defaults to including all TypeScript (.ts, .d.ts and .tsx) files in the containing directory and subdirectories except those excluded using the "exclude" property.

@kyle221b
Copy link

kyle221b commented Apr 8, 2020

@kgaregin Your typeRoots should be only "./typings". Does that work now?

@blakeembrey could you explain why this is the case? Just ran into this on a project I'm working on and trying to understand how this works. I'm guessing it has something to do with using the first declaration found on the path? I tried leaving the path to 'node_modules/@types', but putting it after the custom typings folder in my project, and it also worked.

@blakeembrey
Copy link
Member

@kyle221b I'm pretty sure that comment needs to be read in context, you'll need to see the previous comment. Specifically, that user tried to do ./typings/hapi - I was clarifying for him that it should have only been ./typings and the hapi is added automatically by the TypeScript compiler typing to find hapi.

@kyle221b
Copy link

kyle221b commented Apr 8, 2020

@blakeembrey Ah okay yeah I read it in context. I just took it to mean that you meant to remove the type root referencing "node_modules/@types". I understand what you meant now.

Despite me misinterpreting, when I removed the node modules reference or put the path to my custom typing folder first, ts-node would find the custom type and use it, but when I put the node_modules/@types reference first, it fails to find my custom type.

The actual use case is trying to override some types provided by the Sequelize library. I was curious if you had insight as to why this was the case. Was looking to add some info to the docs but don't have a clear explanation as to why things are working this way

@blakeembrey
Copy link
Member

@kyle221b I'm not 100% sure, but do you happen to have a directory with the same name in both cases? I'd guess TypeScript finds the first match and not the second, so the order you have it in decides the load order.

@haixiangyan
Copy link

haixiangyan commented Apr 19, 2020

I had the same issue. Turns out you need to use ts-node --files app.ts instead of ts-node app.ts.

@andersondanilo
Copy link

I added a file ./typings/express/index.d.ts with the following code:

import { User } from '../../modules/users/models/user'

declare global {
  namespace Express {
    export interface Request {
      user?: User;
    }
  }
}

It was not working, until i inverted type typings and node_modules/@types, it ended like this:

"typeRoots": ["./src/typings", "./node_modules/@types"],

@kyle221b
Copy link

kyle221b commented May 7, 2020

Yup ended up doing the same thing. Was never able to figure out why though

@shane-js
Copy link

shane-js commented May 31, 2020

To help anyone who is just looking for something else to try here is what worked for me when trying to extend ExpressJS' Request. I had to have tried more than a dozen things before getting this to work:

  • Flip the order of what everyone is recommending in the "typeRoots" of your tsconfig.json (and don't forget to drop the src pathing if you have a rootDir setting in tsconfig such as "./src"). Example:
"typeRoots": [
      "./node_modules/@types",
      "./your-custom-types-dir"
]
  • Example of custom extension ('./your-custom-types-dir/express/index.d.ts"). I had to use inline import and default exports to use classes as a type in my experience so that is shown too:
declare global {
  namespace Express {
    interface Request {
      customBasicProperty: string,
      customClassProperty: import("../path/to/CustomClass").default;
    }
  }
}
  • Update your nodemon.json file to add the "--files" command to ts-node, example:
{
  "restartable": "rs",
  "ignore": [".git", "node_modules/**/node_modules"],
  "verbose": true,
  "exec": "ts-node --files",
  "watch": ["src/"],
  "env": {
    "NODE_ENV": "development"
  },
  "ext": "js,json,ts"
}

@abumalick
Copy link

With nodemon in package.json

"scripts": {
    "start:dev": "nodemon -r dotenv/config --watch 'src/**/*.ts' --exec 'ts-node --files' src/server.ts",
  },

@js2me
Copy link

js2me commented Jun 30, 2020

For people who open this issue based on not working typeRoots in VSCode debugger.
Take a look at my launch.json config file. To say ts-node to load files from typeRoots you need to add:

      "env": {
        "TS_NODE_FILES": "true",
        "TS_NODE_PROJECT": "./tsconfig.json"
      },

It works for me
image

@webberwang
Copy link

This issue is re-appaearing in 8.10.2, working with 8.10.1

@pedroSoaresll
Copy link

When using with ts-node you have to add --files flag

ts-node --files src/server.ts 

God! It works for me. Thanks to share its solution.

@inlightmedia
Copy link

inlightmedia commented Jul 29, 2020

We just updated from 8.9.1 to 8.10.1 and this bug cropped up. All our typing settings have been working for years with no problems. It looks like the update broke it. I reverted to 8.9.1 and voila, everything works now.

UPDATE:
When I added the --files flag using the newer version of ts-node (8.10.1) the build was still failing but when I reverted my code I had the --flag set as well. Once I removed the --files flag on the original version it failed.

The strange thing is that we have been using ts-node without the --files flag for years. Also worth noting that this only happens in production. Our local ts-node is run inside nodemon and is unaffected by this bug and does not require the files flag. Both production and our local dev environment all use the same tsconfig.

@cspotcode
Copy link
Collaborator

cspotcode commented Jul 29, 2020

@webberwang @pedroSoaresll @inlightmedia are you able to try the latest code from master? There's an unreleased bugfix on master, and it would be helpful to know whether or not it fixes your issue.

You can download the latest master build from Github Actions: https://github.com/TypeStrong/ts-node/suites/981035643/artifacts/12548599
Then npm install ts-node-packed.tgz.zip
EDIT: This syntax may not be 100% correct but it's explained here: https://docs.npmjs.com/cli/install

We can publish a release over the weekend.

jjenzz added a commit to radix-ui/primitives that referenced this issue Aug 3, 2020
@korenzerah
Copy link

Using ts-node 8.5.0, typescript 3.9.7, trying to add custom declaration file to @x/y package.
typeRoots didn't help:

Folders structure:

- root
    -- src
    -- types
        -- @x
           -- y
                -- index.d.ts
    -- tsconfig.json

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "./",
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "module": "commonjs",
    "outDir": "dist",
    "removeComments": true,
    "sourceMap": true,
    "strict": true,
    "target": "es6",
    "moduleResolution": "node",
    "paths": {
      "@models/*": [
        "src/models/*"
      ],
      "@shared/*": [
        "src/shared/*"
      ],
      "@server": [
        "src/Server"
      ]
    },
    "types": [
      "node"
    ],
    "typeRoots": [
      "types",
      "node_modules/@types"
    ]
  },
  "include": [
    "src/**/*.ts",
  ]
}

only the --files flag worked.
Feels like the wrong solution to include all ts files using the --files flag to make it work.

@cspotcode
Copy link
Collaborator

Try using a triple-slash directive to include the types. https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-

Keep in mind that tsc is effectively always using the --files flag.

@tokisakiyuu
Copy link

When using with ts-node you have to add --files flag

ts-node --files src/server.ts 

thanks!

@daychongyang
Copy link

When using with ts-node you have to add --files flag

ts-node --files src/server.ts 

--files Load files, include and exclude from tsconfig.json on startup

@wzr1337
Copy link

wzr1337 commented May 11, 2021

When using with ts-node you have to add --files flag

ts-node --files src/server.ts 

this still works for me in 2021.. and i do not understand why this is not default behavior

@placideirandora
Copy link

placideirandora commented Jul 20, 2021

looks like it works again with ts-node@8.0.3 version (like this "typeRoots": ["./node_modules/@types", "./typings"])

This has worked for me in 2021 for ts-node@10.1.0.

@rcbevans
Copy link

When using with ts-node you have to add --files flag

ts-node --files src/server.ts 

I just hit this. Why does it work when specifying --files, but not ts-node src/server.ts?

@ledenis
Copy link
Contributor

ledenis commented Apr 1, 2023

By default, ts-node does not load files, include or exclude from tsconfig.json on startup. The --files option enables it.

See https://github.com/TypeStrong/ts-node#missing-types

@TreehouseNorris
Copy link

"Triple-slash directives are only valid at the top of their containing file. A triple-slash directive can only be preceded by single or multi-line comments, including other triple-slash directives. If they are encountered following a statement or a declaration they are treated as regular single-line comments, and hold no special meaning."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests