🔎 Search Terms
@typescript/typescript6, @typescript/old, tsc bin, side-by-side, npm bin conflict
🕗 Version & Regression Information
💻 Code
@typescript/typescript6 declares only the non-conflicting bin, which is correct:
$ node -p "JSON.stringify(require('@typescript/typescript6/package.json').bin)"
{"tsc6":"./bin/tsc6"}
Its dependency does not:
$ node -p "JSON.stringify(require('@typescript/typescript6/package.json').dependencies)"
{"@typescript/old":"npm:typescript@^6"}
$ node -p "JSON.stringify(require('@typescript/old/package.json').bin)"
{"tsc":"./bin/tsc","tsserver":"./bin/tsserver"}
So a project that runs TypeScript 7 as its compiler and keeps 6 available for a tool that still needs the old API:
ends up with the transitive package owning tsc:
$ readlink node_modules/.bin/tsc
../@typescript/old/bin/tsc
$ npx tsc --version
Version 6.0.3
🙁 Actual behavior
node_modules/.bin/tsc resolves to TypeScript 6. Any npm run build whose script is tsc --build ... silently compiles with 6 while the project's declared compiler is 7, and it succeeds, so nothing signals the substitution. I only noticed because a build that should have failed on unstable/* imports (TS1479 under module: node16) passed.
🙂 Expected behavior
Installing the compatibility package alongside TypeScript 7 leaves tsc pointing at TypeScript 7. @typescript/old is an implementation detail of the compatibility package and arguably should not contribute bin entries at all — publishing it without them, or under names that cannot collide, would do it.
Additional information about the issue
The documented side-by-side layout in the 7.0 announcement is the reverse of mine (typescript aliased to 6, @typescript/native for 7), and does not hit this, since tsc pointing at 6 is what that layout intends. The collision shows up in the inverse arrangement, which is the natural one for a project that has already moved to 7 and keeps 6 only for a library dependency.
Workaround is to name the compiler by path in the scripts:
🔎 Search Terms
@typescript/typescript6, @typescript/old, tsc bin, side-by-side, npm bin conflict
🕗 Version & Regression Information
typescript@7.0.2alongside@typescript/typescript6@6.0.2.@typescript/typescript6ships the API under@typescript/old(path-based tooling) #63866 asked for the@typescript/oldlayout to be documented for path-based tooling, and was closed as not planned. This is about thebinentries rather than the library path.💻 Code
@typescript/typescript6declares only the non-conflicting bin, which is correct:Its dependency does not:
So a project that runs TypeScript 7 as its compiler and keeps 6 available for a tool that still needs the old API:
{ "dependencies": { "typescript": "^7.0.2" }, "devDependencies": { "typescript6": "npm:@typescript/typescript6@^6.0.2" } }ends up with the transitive package owning
tsc:🙁 Actual behavior
node_modules/.bin/tscresolves to TypeScript 6. Anynpm run buildwhose script istsc --build ...silently compiles with 6 while the project's declared compiler is 7, and it succeeds, so nothing signals the substitution. I only noticed because a build that should have failed onunstable/*imports (TS1479 undermodule: node16) passed.🙂 Expected behavior
Installing the compatibility package alongside TypeScript 7 leaves
tscpointing at TypeScript 7.@typescript/oldis an implementation detail of the compatibility package and arguably should not contributebinentries at all — publishing it without them, or under names that cannot collide, would do it.Additional information about the issue
The documented side-by-side layout in the 7.0 announcement is the reverse of mine (
typescriptaliased to 6,@typescript/nativefor 7), and does not hit this, sincetscpointing at 6 is what that layout intends. The collision shows up in the inverse arrangement, which is the natural one for a project that has already moved to 7 and keeps 6 only for a library dependency.Workaround is to name the compiler by path in the scripts: