Using node v11.12.0 and ts-node v8.3.0, I get different behaviour between tsc running inside a langauge server in vscode 3.5.2 (node_modules has 3.5.3) for extended interfaces, when running with node -r ts-node/register.
The full command line is: TS_NODE_PROJECT=tsconfig.server.json node --inspect=9229 -r ts-node/register server/index.ts.
tsconfig.json has contents:
{
"compilerOptions": {
"allowJs": true,
"downlevelIteration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"preserveConstEnums": true,
"removeComments": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictNullChecks": true,
"target": "es2020",
"typeRoots": [
"./node_modules/@types",
"./types"
]
},
"exclude": [
"node_modules",
"cypress",
"dist",
"next.config.js"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
]
}
and tsconfig.server.json:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "dist",
"target": "es2017",
"isolatedModules": false,
"noEmit": false
}
}
does not apply, but causes an error. Folder structure;
$ tree types
types
├── custom.d.ts
├── dom.d.ts
├── express
│  └── index.d.ts
Contents of index.d.ts:
declare module 'http' {
export interface IncomingMessage {
logger: import('../../lib/logary/logger').SpanLogger;
}
}
Error:
[nodemon] starting `node -r ts-node/register server/index.ts`
site/node_modules/ts-node/src/index.ts:245
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
server/idp/login.ts:18:9 - error TS2339: Property 'logger' does not exist on type 'Request'.
18 req.logger.info("GET /accounts/login Missing `login_challenge` param")
~~~~~~
at createTSError (site/node_modules/ts-node/src/index.ts:245:12)
at reportTSError (site/node_modules/ts-node/src/index.ts:249:19)
at getOutput (site/node_modules/ts-node/src/index.ts:362:34)
at Object.compile (site/node_modules/ts-node/src/index.ts:395:32)
at Module.m._compile (site/node_modules/ts-node/src/index.ts:473:43)
at Module._extensions..js (internal/modules/cjs/loader.js:810:10)
at Object.require.extensions.(anonymous function) [as .ts] (site/node_modules/ts-node/src/index.ts:476:12)
at Module.load (internal/modules/cjs/loader.js:666:32)
at tryModuleLoad (internal/modules/cjs/loader.js:606:12)
at Function.Module._load (internal/modules/cjs/loader.js:598:3)
workaround that makes it work:
/// <reference types="../../types/express" />
/// <reference types="../../node_modules/@types/express" />
This means that ts-node when used via ts-node/register does not load the typescript definitions from the configured folders.
This issue has a long discussion showing approximately the same:
https://github.com/TypeStrong/ts-node/issues/782#issuecomment-496685993
Yes, I have read the docs, both the handbook and the readme about types; hence the pun in the title of this issue. I think it's an issue since ts-node and the ts lang server diverge.
Why don't you just run it with --files? The reason it's this way by default is because there are just as many people complaining about performance, which deferring loading everything within a project for a file or two is an easy win.
Looking back now that you've told me the solution; for a few different reasons;
ts-node/register is only documented deep down in a comment thread accessible by searching for it and then it's only with a single sentence akin to "try this", so there's no documentation specifying the invariants I can expect to rely on when using it--files in the docs multiple times during setting it up, but I'm not looking to specify multiple files, only the project file, which is what I am setting with TS_NODE_PROJECT; however, I now know that I also have to encourage it with TS_NODE_FILES=true.TS_NODE_FILES also confused me with the "files"-property in tsconfig.jsontsconfig.json to use typeRoots and then telling ts-node to use tsconfig.json to mean that it did use (all of) tsconfig.json.tsconfig.json by default for ts-node is undocumented.On the files flag and files file array; suggestion — it's not really the "files" I want to compile that we're talking about here, so you could still start by only looking at the entrypoint file and then when type resolution is needed for non-local (to the entrypoint) types, load the typeRoots' files.
About compilation latency; it's irrelevant for me since nextjs is the second thing that starts, and I presume that starts a second typescript compiler all on its own inside the express process, and that means I have to wait for it to fully type-check every file in my project anyway. That's where I have latency (about 40 seconds of it) that I would like to reduce, if any.
I expected me configuring tsconfig.json to use typeRoots and then telling ts-node to use tsconfig.json to mean that it did use (all of) tsconfig.json.
It does and did, I think the configuration of typeRoots is incorrect. TypeScript only found the first one. If you had named it express-logging-extension or something this would be a non-issue.
so you could still start by only looking at the entrypoint file and then when type resolution is needed for non-local (to the entrypoint) types, load the typeRoots' files.
Yes, this is how it works today. Except all these details are within TypeScript and not ts-node.
About compilation latency; it's irrelevant for me since nextjs is the second thing that starts, and I presume that starts a second typescript compiler all on its own inside the express process, and that means I have to wait for it to fully type-check every file in my project anyway.
Wouldn't this imply that running two compilers would actually run at 2x 40s?
The reason I offered --files as a solution originally is specifically because you commented on the tsc vs ts-node disparity FWIW. The typeRoots gotcha is something I wouldn't have noticed if I hadn't debugged this once before for someone else :frowning:
Most helpful comment
Looking back now that you've told me the solution; for a few different reasons;
ts-node/registeris only documented deep down in a comment thread accessible by searching for it and then it's only with a single sentence akin to "try this", so there's no documentation specifying the invariants I can expect to rely on when using it--filesin the docs multiple times during setting it up, but I'm not looking to specify multiple files, only the project file, which is what I am setting withTS_NODE_PROJECT; however, I now know that I also have to encourage it withTS_NODE_FILES=true.TS_NODE_FILESalso confused me with the"files"-property intsconfig.jsontsconfig.jsonto use typeRoots and then tellingts-nodeto usetsconfig.jsonto mean that it did use (all of)tsconfig.json.tsconfig.jsonby default forts-nodeis undocumented.On the
filesflag andfilesfile array; suggestion — it's not really the "files" I want to compile that we're talking about here, so you could still start by only looking at the entrypoint file and then when type resolution is needed for non-local (to the entrypoint) types, load thetypeRoots' files.About compilation latency; it's irrelevant for me since nextjs is the second thing that starts, and I presume that starts a second typescript compiler all on its own inside the express process, and that means I have to wait for it to fully type-check every file in my project anyway. That's where I have latency (about 40 seconds of it) that I would like to reduce, if any.