Skip to content

@typescript/old declares a tsc bin that wins over typescript@7 when the 6.0 compat package is installed #64071

Description

🔎 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:

{
  "dependencies":    { "typescript": "^7.0.2" },
  "devDependencies": { "typescript6": "npm:@typescript/typescript6@^6.0.2" }
}

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:

"build": "node_modules/typescript/bin/tsc --build tsconfig.build.json"

Metadata

Metadata

Assignees

No one assigned

    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