Some dependency JS files appear to be erroneously typechecked
When I built my project in TS-Go I ended up getting thousands of errors. While I'm still working through some of them to make more reports, the ones that struck me as most obviously problematic is thousands of errors in .js files in dependencies.
I decided to minimize my repo's code into something easier to investigate.
// index.ts
import "vitest/config";
import "simple-peer";
// package.json
{
"dependencies": {
"@types/simple-peer": "~9.11.1",
"@typescript/native-preview": "^7.0.0-dev.20250523.1",
"typescript": "^5.8.3",
"vite": "^6.3.5",
"vitest": "^3.0.5"
}
}
// tsconfig.json
{
"$schema": "https://json.schemastore.org/tsconfig.json",
"compilerOptions": {
"target": "ESNext",
"module": "NodeNext",
"noEmit": true,
"noUncheckedSideEffectImports": true, // Optional
"allowJs": true,
"checkJs": true
}
}
Here's that same code as a zip: dependency-js-errors.zip.
When npx tsc is run there are 0 errors, when npx tsgo is run this is the summary of the errors:
Found 321 errors in 4 files.
Errors Files
305 node_modules/chai/chai.js:13
8 node_modules/vitest/dist/chunks/reporters.d.C-cu31ET.d.ts:5
2 node_modules/vitest/dist/chunks/vite.d.iXCEVtFP.d.ts:1
6 node_modules/vitest/dist/config.d.ts:1
My original repo experienced many more errors due to stricter tsconfig rules but I suspect that fixing these errors will fix the JS errors in my repo.
I stopped my reduction scripts once they had reduced down to minimal code in my own repo but if you'd my to help reducing the dependencies as well I'd be happy to help.
BTW, I tried this PR against #930 and it did not fix the issue. @jakebailey was this something that was intended to be fixed in your PR?
I wouldn't think so, given you have checkJs on and my PR would only fix errors when it's off.
Things should have improved here, can you retest?
@jakebailey If I take that zip, update tsgo with npm add -D @typescript/native-preview, and then run npx tsgo I unfortunately get this panic:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x76be31]
goroutine 31 [running]:
github.com/microsoft/typescript-go/internal/ast.(*Node).IsTypeOnly(...)
github.com/microsoft/typescript-go/internal/ast/ast.go:671
github.com/microsoft/typescript-go/internal/checker.(*Checker).resolveExternalModule(0xc003651008, 0xc0001a0180, {0xc000182080, 0xd}, 0x11317e0, 0xc0001aa090, 0x0)
github.com/microsoft/typescript-go/internal/checker/checker.go:14425 +0x12b1
github.com/microsoft/typescript-go/internal/checker.(*Checker).resolveExternalModuleNameWorker(0xc003651008, 0xc0001a0180, 0xc0001aa090, 0x11317e0, 0x0, 0x0)
github.com/microsoft/typescript-go/internal/checker/checker.go:14298 +0x85
github.com/microsoft/typescript-go/internal/checker.(*Checker).resolveExternalModuleName(0xc003651008?, 0xc0001a0180?, 0xc003ca6460?, 0x10?)
github.com/microsoft/typescript-go/internal/checker/checker.go:14293 +0x33
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkImportDeclaration(0xc003651008, 0xc0001a0180)
github.com/microsoft/typescript-go/internal/checker/checker.go:5003 +0x26e
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElementWorker(0xc003651008, 0xc0001a0180)
github.com/microsoft/typescript-go/internal/checker/checker.go:2252 +0x3a5
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElement(0xc003651008, 0xc00467d1a0?)
github.com/microsoft/typescript-go/internal/checker/checker.go:2134 +0x4e
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceElements(0xc003651008, {0xc000194080, 0x2, 0xc003fb5ef8?})
github.com/microsoft/typescript-go/internal/checker/checker.go:2125 +0x2d
github.com/microsoft/typescript-go/internal/checker.(*Checker).checkSourceFile(0xc003651008, {0xc6b460, 0x1171060}, 0xc0001ae008)
github.com/microsoft/typescript-go/internal/checker/checker.go:2097 +0x11c
github.com/microsoft/typescript-go/internal/checker.(*Checker).CheckSourceFile(0xc003651008, {0xc6b460, 0x1171060}, 0xc0001ae008)
github.com/microsoft/typescript-go/internal/checker/checker.go:2086 +0x51
github.com/microsoft/typescript-go/internal/compiler.(*Program).CheckSourceFiles.func1-range1(0x1?)
github.com/microsoft/typescript-go/internal/compiler/program.go:353 +0x3e
github.com/microsoft/typescript-go/internal/compiler.(*checkerPool).Files.func1(0xc00467d170)
github.com/microsoft/typescript-go/internal/compiler/checkerpool.go:82 +0x88
github.com/microsoft/typescript-go/internal/compiler.(*Program).CheckSourceFiles.func1()
github.com/microsoft/typescript-go/internal/compiler/program.go:352 +0xe2
github.com/microsoft/typescript-go/internal/core.(*parallelWorkGroup).Queue.func1()
github.com/microsoft/typescript-go/internal/core/workgroup.go:39 +0x50
created by github.com/microsoft/typescript-go/internal/core.(*parallelWorkGroup).Queue in goroutine 1
github.com/microsoft/typescript-go/internal/core/workgroup.go:37 +0x85
I don't see the crash, but it does emit a bunch of errors:
...
~~~~~~~~~~~~~~~~~~~~~~~
node_modules/chai/chai.js:1380:30 - An argument for 'ssfi' was not provided.
1380 function Assertion(obj, msg, ssfi, lockSsfi) {
~~~~
node_modules/chai/chai.js:4058:3 - error TS2350: Only a void function can be called with the 'new' keyword.
4058 new Assertion(val, msg).to.not.containSubset(exp);
~~~~~~~~~~~~~~~~~~~~~~~
node_modules/chai/chai.js:4058:3 - error TS2554: Expected 4 arguments, but got 2.
4058 new Assertion(val, msg).to.not.containSubset(exp);
~~~~~~~~~~~~~~~~~~~~~~~
node_modules/chai/chai.js:1380:30 - An argument for 'ssfi' was not provided.
1380 function Assertion(obj, msg, ssfi, lockSsfi) {
~~~~
Found 294 errors in the same file, starting at: node_modules/chai/chai.js:13
Oddly, this one chai file is added to the program in tsgo, but not in tsc.
I feel like this must be a module resolution bug. I added some extra logging, and:
In /home/jabaile/work/repros/tsgo931/node_modules/vitest/dist/config.d.ts
resolved module chai to /home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js with mode ModuleKindESNext
In /home/jabaile/work/repros/tsgo931/node_modules/vitest/dist/chunks/reporters.d.C-cu31ET.d.ts
resolved module chai to /home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js with mode ModuleKindESNext
Found 294 errors in the same file, starting at: node_modules/chai/chai.js:13
For some reason, we're resolving the import chai inside the package to chai.js and then we include it.
That or, it's just specifically that we're not excluding that in file loading? Need to cross check Strada.
We have node modules depth to not add files after certain depth in node modules .. that part is bot ported yet ..
I guess it could just be that. I was assuming that because this is a "real" project that the depth thing has nothing to do with it.
Huh, no, I'm just wrong. The code really doesn't care, it's just that we set it to zero normally. I'll try and port that code quick.
The concurrency makes this not simple, who would have guessed.
@jakebailey the version I installed that had the crash was 7.0.0-dev.20250604.1 (the latest available at the time). It looks like the crash was fixed in 7.0.0-dev.20250606.1 and has stayed fixed since then.
@LukeAbby Can you try #1189 out? I believe it fixes your problem.
$ tsgo --listFilesOnly | grep chai
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
$ tsgo --listFilesOnly --maxNodeModuleJsDepth 1 | grep chai
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js
Then again:
$ npx tsc --listFilesOnly | grep chai
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
$ npx tsc --listFilesOnly --maxNodeModuleJsDepth 1 | grep chai
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
So, maybe not quite perfect yet (but seemingly still helps).
I can confirm I no longer get any suspicious JS file errors! It sounds like it might not work for someone else but for me it's perfect. I'll file another issue if I run into it again of course.
Fixed the above discrepency in the PR:
$ for i in $(seq 0 5); do echo "depth=$i tsgo"; ~/work/TypeScript-go/built/local/tsgo --listFilesOnly --maxNodeModuleJsDepth $i | grep chai; echo "depth=$i tsc"; npx tsc --listFilesOnly --maxNodeModuleJsDepth $i | grep chai; echo; done
depth=0 tsgo
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
depth=0 tsc
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
depth=1 tsgo
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
depth=1 tsc
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
depth=2 tsgo
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
depth=2 tsc
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
depth=3 tsgo
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js
depth=3 tsc
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js
depth=4 tsgo
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js
depth=4 tsc
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js
depth=5 tsgo
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js
depth=5 tsc
/home/jabaile/work/repros/tsgo931/node_modules/@vitest/expect/dist/chai.d.cts
/home/jabaile/work/repros/tsgo931/node_modules/chai/chai.js