microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.21k stars 12.51k forks source link

Module resolution: Module resolved to indirect dependency rather than direct local one when versions are the same #60556

Open grigasp opened 2 days ago

grigasp commented 2 days ago

🔎 Search Terms

"local module resolution", "module resolution same version"

🕗 Version & Regression Information

⏯ Playground Link

https://github.com/grigasp/ts-deps-issue

💻 Code

Package a@1.0.0 is released with the following:

export type A1 = number;

Locally we have this package at the same version, but with an additional type:

export type A1 = number;
export type A2 = string;

Locally we also have a package b, that has a dependency on a released version of a@1.0.0 and exports the following type:

import { A1 } from "a";
export type B = A1;

Finally, locally we also have a package c, that has dependencies on local workspace versions of packages b and a and imports types from them both:

// Switching order of these import fixes the build
import { B } from "b";
import { A2 } from "a";

const b: B = 1;
const a2: A2 = "a2";

🙁 Actual behavior

When building package c, the build fails with error:

> c@1.0.0 build
> tsc

src/index.ts:3:10 - error TS2305: Module '"a"' has no exported member 'A2'.

3 import { A2 } from "a";

🙂 Expected behavior

When building package c, TypeScript resolves package a to our local version which does have the A2 type, and the build succeeds.

Additional information about the issue

I tried running tsc -traceResolution for package c and it seems that both - released package and the local one - are assigned the same Package ID:

...
======== Resolving module 'a' from 'E:/temp/ts-deps-issue/packages/c/src/index.ts'. ========
...
======== Module name 'a' was successfully resolved to 'E:/temp/ts-deps-issue/packages/a/lib/index.d.ts' with Package ID 'a/lib/index.d.ts@1.0.0'. ========

======== Resolving module 'a' from 'E:/temp/ts-deps-issue/packages/b/lib/index.d.ts'. ========
...
======== Module name 'a' was successfully resolved to 'E:/temp/ts-deps-issue/node_modules/.pnpm/a@file+packages+a+a-1.0.0.tgz/node_modules/a/lib/index.d.ts' with Package ID 'a/lib/index.d.ts@1.0.0'. ========
...

I suppose that could cause a cache collision or something like that.