TypeStrong / TypeStrong/ts-loader

Incorrect getScriptFileNames/getRootFileNames causes resolution bugs

Open
#949 9 comments 2 reactions 1 assignee View on GitHub

@andrewbranch is already working on this.

Since Jun 7, 2019.

bug pinned
Dominant language
TypeScript
Stars
3.5k
Forks
439
Avg merge
17h 17m
Merged PRs (30d)
2

Description

I'm not even going to try to figure out a minimal repro, but I'm observing it happening in a real-world project while testing #935. Basically, this

https://github.com/TypeStrong/ts-loader/blob/d677d7359e863079e585310b105cfa9c45acf555/src/servicesHost.ts#L100

is supposed to return only the root file names, i.e., what TypeScript sees as “entrypoints,” i.e., excluding libs and imported modules that aren’t covered by include or files in the tsconfig.

However, what it’s doing here is returning all the script files Webpack knows about, in no particular order. This is a problem because later on, TypeScript will try to merge this array of files with more files, and the resulting order is important. However, since this array already contains all the other things TypeScript is trying to merge in, it’s a no-op and that important ordering never happens.

The particular symptom I’m observing is that, with transpileOnly: false, my project compiles cleanly in the initial run, but when I modify a file that assumes the return value of setTimeout is a number (which it is in the browser), I get errors because the type checker thinks setTimeout is coming from @types/node (which returns an object).

What’s happening under the hood is that on the first run, ts-loader isn’t yet aware of any lib files, so getScriptFileNames() works, and TypeScript sorts lib files and typings files appropriately, such that the symbol for setTimeout has a valueDeclaration coming from lib.dom.d.ts, and some other declarations from @types/node. But on the second run, ts-loader’s instance.files contains lib files and typings for Node, and the ones for Node happen to come first, so that becomes the valueDeclaration for the global symbol setTimeout.

I actually think #348 might have been caused by this.

At any rate, I’m going to fix it. Just wanted to document it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.