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.
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)
rebolyte, czaas, Hugheth, felixscheffer, gogakoreli, tomchambers2, hanshou101, dingyanhe, ultrafez, iki, and 5 more reacted with thumbs up emoji
haf, gregsolo-intent, nosuchip, balazsbotond, altjz, robertpitt, SCLeoX, tenoriojuann, slaveofcode, SnitchRUS66, and 89 more reacted with thumbs down emoji
All reactions
👍 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:
> [email protected] 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 😞
"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.
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.
aleixsuau, tamj0rd2, patarapolw, scriptcoded, houd1ni, InsOpDe, levenleven, DullReferenceException, iki, and domilin reacted with thumbs up emoji
zerubeus, antoinerousseau, kytosai, mkg0, aprilmintacpineda, and godzzo reacted with thumbs down emoji
domilin reacted with laugh emoji
aleixsuau, houd1ni, and domilin reacted with hooray emoji
domilin and Ge-yuan-jun reacted with heart emoji
aleixsuau, houd1ni, domilin, and TreehouseNorris reacted with rocket emoji
domilin reacted with eyes emoji
All reactions
VictorioBerra, CoolHandLuke88, radicand, atomanyih, malkevych, and pierissimo reacted with thumbs up emoji
malkevych reacted with hooray emoji
malkevych reacted with heart emoji
malkevych reacted with rocket emoji
All reactions
js2me, quanghuy17media, tokland, jonocairns, danbergelt, yuyake0084, beInDev, yuhengshen, jherey, valtrem, and 163 more reacted with thumbs up emoji
kemicofa, ystarlongzi, biowaffeln, and godzzo reacted with thumbs down emoji
bozdoz, keletsomolefe, williamdes, zerubeus, kangyunu, mkosir, pedroSoaresll, GGAlanSmithee, theoparis, kayk1m, and 16 more reacted with laugh emoji
stevepsharpe, samsoedien, sun-slaven, kimhansuk, evenfrost, zerubeus, ledenis, js2me, ikopenkov, slaveofcode, and 74 more reacted with hooray emoji
darkbasic, guidodizi, MohammadMRD, bozdoz, keletsomolefe, adannup, williamdes, pedrotorchio, wwwebman, zerubeus, and 47 more reacted with heart emoji
darkbasic, guidodizi, bozdoz, keletsomolefe, deanshelton913, adannup, zerubeus, kangyunu, mkosir, GuyMcNally, and 34 more reacted with rocket emoji
basketball7hero, vialoh, Muhammed-Rahif, and tomaszslabon reacted with eyes emoji
All reactions
prevostc, qinzcm, TugayYaldiz, e00dan, padaw, joseluissb, jazzfog, CONST8, markplindsay, Moutah, and 17 more reacted with thumbs up emoji
Kevin-Andries and cSarcasme reacted with hooray emoji
jazzfog, randowize, 3b40eb98, vladimirnani, camilo86, kimyvgy, and cSarcasme reacted with heart emoji
cSarcasme reacted with rocket emoji
All reactions
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
Create a file located at typings/express/index.d.ts
:
declare namespace Express {
export interface Request {
token: string;
Add the typeRoots
entry in the tsconfig.json
, with the right order :
"compilerOptions": {
"typeRoots": [
"./typings",
"./node_modules/@types"],
hanjeahwan, tomonari-t, codingwithmanny, rogerpadilla, zebkailash, jeromewir, Yaojian, danielgormly, Striar-Yunis, brenomr, and 5 more reacted with thumbs up emoji
Striar-Yunis, keepsoftware, 3b40eb98, SethRogers7420, and olarra reacted with hooray emoji
All reactions
@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.
@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
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.
@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.
@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.
@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.
@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
.
@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
KoltesDigital, sajadghawami, pepijnverburg, wagnercosta, IstoraMandiri, benbenbenbenbenben, SnosMe, hexianzhi, rijkvanzanten, danawoodman, and 18 more reacted with thumbs up emoji
dannysofftie, wagnercosta, IstoraMandiri, SnosMe, danawoodman, elie222, ezze, and carlosflai reacted with hooray emoji
hexianzhi, rijkvanzanten, danawoodman, elie222, kawamataryo, jpcarpanezi, carlosflai, and dpejic reacted with heart emoji
hexianzhi, danawoodman, lmakarov, elie222, and carlosflai reacted with rocket emoji
All reactions
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"],
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"
With nodemon in package.json
"scripts": {
"start:dev": "nodemon -r dotenv/config --watch 'src/**/*.ts' --exec 'ts-node --files' src/server.ts",
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
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.
@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.
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
-- 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.
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.
looks like it works again with [email protected] version (like this "typeRoots": ["./node_modules/@types", "./typings"])
This has worked for me in 2021 for [email protected].
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
"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."