Steps to reproduce
Clone the minimal repro: https://github.com/Cellule/tsgo-outdir-repro
Run npx --package=@typescript/native-preview@7.0.0-dev.20260130.1 tsgo -p sub/tsconfig.json
Observe that common/src/greeter.js is emitted next to the source file instead of in sub/dist/
Project structure
.
├── tsconfig.json # parent config with outDir: "${configDir}/dist/"
├── common/src/greeter.ts # shared source file
└── sub/
├── tsconfig.json # extends ../tsconfig.json, includes ../common/src/**/*
└── src/index.ts # imports from ../../common/src/greeter.js
tsconfig.json (root):
{
"compilerOptions" : {
"target" : " ES2024" ,
"module" : " NodeNext" ,
"moduleResolution" : " NodeNext" ,
"outDir" : " ${configDir}/dist/" ,
"strict" : true ,
"skipLibCheck" : true
},
"include" : [" common/src/**/*" ]
}
sub/tsconfig.json :
{
"extends" : " ../tsconfig.json" ,
"include" : [
" src/**/*" ,
" ../common/src/**/*"
]
}
Behavior with typescript@5.9
All output files are correctly placed in sub/dist/:
$ npx --package=typescript@5.9 tsc -p sub/tsconfig.json && find . -name '*.js' -not -path '*/node_modules/*'
./sub/dist/sub/src/index.js
./sub/dist/common/src/greeter.js
Behavior with tsgo (@typescript/native-preview@7.0.0-dev.20260130.1)
Files from parent directories (included via ../) are emitted next to the source files instead of in outDir:
$ npx --package=@typescript/native-preview@7.0.0-dev.20260130.1 tsgo -p sub/tsconfig.json && find . -name '*.js' -not -path '*/node_modules/*'
./sub/dist/src/index.js # file inside sub/ goes to sub/dist/ ✅
./common/src/greeter.js # file outside sub/ emitted next to source ❌
Note: --showConfig reports the correct resolved outDir:
"outDir": "/path/to/sub/dist"
Bisect result
Last good version : 7.0.0-dev.20260109.1
First bad version : 7.0.0-dev.20260111.1
The regression was introduced between these two nightly builds. The 5 commits in that range are:
2a31979f — Preallocate types slice in getLiteralTypeFromProperties (Preallocate types slice in getLiteralTypeFromProperties #2458 )
38353bd4 — New auto-import infrastructure (New auto-import infrastructure #2390 )
43313db8 — Also clean CI runner for smoke test (Also clean CI runner for smoke test #2464 )
0f7cc3dd — Handle long paths in native-preview tsgo entrypoint (Handle long paths in native-preview tsgo entrypoint #2448 )
6e1e2c29 — Cache types computed by getLiteralTypeFromProperties (Cache types computed by getLiteralTypeFromProperties #2466 )
The most likely culprit is #2390 as the only substantial change touching the compiler.
Additional notes
The issue is not specific to ${configDir} — using "outDir": "./dist/" produces the same result
Setting rootDir explicitly does not fix it
The issue occurs both with and without --build
The issue also affects the latest nightly (7.0.0-dev.20260206.1)
Steps to reproduce
npx --package=@typescript/native-preview@7.0.0-dev.20260130.1 tsgo -p sub/tsconfig.jsoncommon/src/greeter.jsis emitted next to the source file instead of insub/dist/Project structure
tsconfig.json(root):{ "compilerOptions": { "target": "ES2024", "module": "NodeNext", "moduleResolution": "NodeNext", "outDir": "${configDir}/dist/", "strict": true, "skipLibCheck": true }, "include": ["common/src/**/*"] }sub/tsconfig.json:{ "extends": "../tsconfig.json", "include": [ "src/**/*", "../common/src/**/*" ] }Behavior with
typescript@5.9All output files are correctly placed in
sub/dist/:Behavior with
tsgo(@typescript/native-preview@7.0.0-dev.20260130.1)Files from parent directories (included via
../) are emitted next to the source files instead of inoutDir:Note:
--showConfigreports the correct resolvedoutDir:Bisect result
7.0.0-dev.20260109.17.0.0-dev.20260111.1The regression was introduced between these two nightly builds. The 5 commits in that range are:
2a31979f— Preallocate types slice in getLiteralTypeFromProperties (Preallocate types slice in getLiteralTypeFromProperties #2458)38353bd4— New auto-import infrastructure (New auto-import infrastructure #2390)43313db8— Also clean CI runner for smoke test (Also clean CI runner for smoke test #2464)0f7cc3dd— Handle long paths in native-preview tsgo entrypoint (Handle long paths in native-preview tsgo entrypoint #2448)6e1e2c29— Cache types computed by getLiteralTypeFromProperties (Cache types computed bygetLiteralTypeFromProperties#2466)The most likely culprit is #2390 as the only substantial change touching the compiler.
Additional notes
${configDir}— using"outDir": "./dist/"produces the same resultSettingrootDirexplicitly does not fix it--build7.0.0-dev.20260206.1)