Skip to content

tsgo emits files next to source instead of outDir when include references parent directories via ../ #2708

@Cellule

Description

@Cellule

Steps to reproduce

  1. Clone the minimal repro: https://github.com/Cellule/tsgo-outdir-repro
  2. Run npx --package=@typescript/native-preview@7.0.0-dev.20260130.1 tsgo -p sub/tsconfig.json
  3. 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:

  1. 2a31979f — Preallocate types slice in getLiteralTypeFromProperties (Preallocate types slice in getLiteralTypeFromProperties #2458)
  2. 38353bd4 — New auto-import infrastructure (New auto-import infrastructure #2390)
  3. 43313db8 — Also clean CI runner for smoke test (Also clean CI runner for smoke test #2464)
  4. 0f7cc3dd — Handle long paths in native-preview tsgo entrypoint (Handle long paths in native-preview tsgo entrypoint #2448)
  5. 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)

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions