Closed
Description
Motivation
We currently have tsc --listFiles
to show the list of files included in the compilation, but it doesn't tell you why a file is in there. There are other scenarios where a file is "illegally" part of the compilation, but we're not able to tell you why it's there.
This leads to some difficult debugging scenarios. For example, a customer was confused about why the ES2018 includes
method was available in their ES5-targeting program:
(Customer) Here's a dumb question. Array.prototype.includes is part of ES7. In our tsconfig.json we target es6 and lib is just [ "es6" ]. Should I get compilation errors when trying to call includes? If not, should the generate code have called includes? How can I learn what the mental model I should be using is here.
(Me) You should see an error. Typescript never polyfills any APIs
(Customer) Would having "@types/node": "latest" in my package.json change the behavior here?
(Me) Yeah it's possible node dts pulls in additional stuff, but they shouldn't do anything that would bring in includes
(Me) that'd be a node dts bug imho
(Customer) So with it, it definitely builds. But the only place they have an includes is as a method on the Buffer class.
(Me) Where does go to def take you?
(Customer) /usr/share/code/resources/app/extensions/node_modules/typescript/lib/lib.es2016.array.include.d.ts
(Customer) Which is ES7?
(Customer) Yeah - sorry - surprised that go-to def would bring me to lib.es2016.ANYTHING if I was using the es6 target and lib?
(Me) You are correctly surprised
(Me) It means something has a lib reference that's causing it to be included
(Me) Search for "reference lib=" in your project
(Customer) Aside from a bunch of hits in node_modules/typescript, there only other hits are in the @types/node module here: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/ts3.2/index.d.ts
(Me) So yeah that file is pulling in es2018
Suggestion
During program creation, the first time a file is added to the program, we should keep track of what caused this to happen - lib
reference, types
directive, etc., and resurface that data when needed.
Examples
--listFiles
> tsc --listFiles
node_modules/typescript/lib/lib.es5.d.ts Automatic for target: "es5"
node_modules/typescript/lib/lib.es2015.d.ts lib reference from node_modules/typescript/lib/lib.es2016.d.ts
node_modules/typescript/lib/lib.es2016.d.ts Included from lib: "es2016"
src/compiler/core.ts Part of 'files' list in tsconfig.json
src/compiler/debug.ts Matched by include pattern '*/debug.ts' in tsconfig.json
src/compiler/performance.ts Included via reference from src/compiler/core.ts
node_modules/@types/microsoft__typescript-etw/index.d.ts Imported from src/compiler/performance.ts
src/compiler/perfLogger.ts Part of 'files' list in tsconfig.json
src/compiler/semver.ts Part of 'files' list in tsconfig.json
src/compiler/types.ts Part of 'files' list in tsconfig.json
node_modules/buffer/index.d.ts Imported from node_modules/@types/node/globals.d.ts
node_modules/@types/node/globals.d.ts Entry point for implicit types library 'node'
rootDir
violations
> tsc
Error TS1236: File "test/list.ts" is outside rootDir "src"
The file is in the program because: Matched by default include pattern "**/*"
> tsc
Error TS1236: File "test/list.ts" is outside rootDir "src"
The file is in the program because: Imported by "src/bad_file.ts"