Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typeVersions substitution occurs multiple times causing resolution to fail #41284

Open
Gozala opened this issue Oct 27, 2020 · 3 comments
Open
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@Gozala
Copy link

Gozala commented Oct 27, 2020

TypeScript Version: 4.0.3, 4.1.0-dev.20201027

When module direcotry is imported which is mapped to typedefs through typeVersions typescript ends up doing path substitution multiple times and ends up with a wrong lookup path leading to failed resolution. I have created minimal reproducible example https://github.com/Gozala/bug-tsc-path-substitution/tree/double-substitution

Where you can see that src/index.ts imports bar/src module which seems to do the following:

  1. typesVersion substitution is applied to 'src', which matched pattern '*'

    Trying substitution 'dist/*', candidate module location: 'dist/src'.

  2. Which triggers following lookups:
  • node_modules/bar/dist/src.ts
  • node_modules/bar/dist/src.tsx
  • node_modules/bar/dist/src.d.ts
  1. After neither found instead of looking up at node_modules/bar/dist/src/index.(ts,tsx,d.ts) it seems to look at 'package.json' 'main' field and do second path substitution:

    'package.json' has 'main' field 'src/index.js' that references 'node_modules/bar/dist/src/src/index.js'.

  2. Which fails because it ends up looking for dist/src/dist/src/index instead of dist/src/index.
  3. This is especially problematic because typescript seems to generate import paths like bar/src in place of bar as illustrated by node_modules/foo/ where original import was for bar but typedefs emitted have bar/src instead (for no apparent reason)

Search Terms:

  • module resolution
  • typeVersions
  • double substitution

Code

Expected behavior:

After considering following paths:

  • node_modules/bar/dist/src.ts
  • node_modules/bar/dist/src.tsx
  • node_modules/bar/dist/src.d.ts

Following paths should be considered

  • node_modules/bar/dist/src/index.ts
  • node_modules/bar/dist/src/index.tsx
  • node_modules/bar/dist/src/index.d.ts

Actual behavior:

Instead after considering following paths

After considering following paths:

  • node_modules/bar/dist/src.ts
  • node_modules/bar/dist/src.tsx
  • node_modules/bar/dist/src.d.ts

TS seems to do another path substitute for dist/src/index.js ends up with wrong path node_modules/bar/dist/src/dist/src/index.js which cases failure in finding dist/src/index.d.ts

Playground Link:

Can't demonstrate with playground, as many files are involved. Please see demo repo instead
https://github.com/Gozala/bug-tsc-path-substitution/tree/double-substitution

Related Issues:

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Nov 4, 2020
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.2.0 milestone Nov 4, 2020
@RyanCavanaugh RyanCavanaugh added the Rescheduled This issue was previously scheduled to an earlier milestone label Mar 4, 2021
Gozala added a commit to multiformats/js-multiformats that referenced this issue Mar 30, 2021
- "*" match seems to cause multiple path substitutions
microsoft/TypeScript#41284 that packge name prefix seems to resolve
- add types field which acts as main in TS
Gozala added a commit to multiformats/js-multiformats that referenced this issue Mar 30, 2021
- modify scripts to use newer tsc --bulid command
- generate types on prepare so linking to git dependency works
- workaround douple substitution by mapping types/* to itself
   (see microsoft/TypeScript#41284)
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- "*" match seems to cause multiple path substitutions
microsoft/TypeScript#41284 that packge name prefix seems to resolve
- add types field which acts as main in TS
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- modify scripts to use newer tsc --bulid command
- generate types on prepare so linking to git dependency works
- workaround douple substitution by mapping types/* to itself
   (see microsoft/TypeScript#41284)
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- "*" match seems to cause multiple path substitutions
microsoft/TypeScript#41284 that packge name prefix seems to resolve
- add types field which acts as main in TS
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- modify scripts to use newer tsc --bulid command
- generate types on prepare so linking to git dependency works
- workaround douple substitution by mapping types/* to itself
   (see microsoft/TypeScript#41284)
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- "*" match seems to cause multiple path substitutions
microsoft/TypeScript#41284 that packge name prefix seems to resolve
- add types field which acts as main in TS
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- modify scripts to use newer tsc --bulid command
- generate types on prepare so linking to git dependency works
- workaround douple substitution by mapping types/* to itself
   (see microsoft/TypeScript#41284)
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- "*" match seems to cause multiple path substitutions
microsoft/TypeScript#41284 that packge name prefix seems to resolve
- add types field which acts as main in TS
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- modify scripts to use newer tsc --bulid command
- generate types on prepare so linking to git dependency works
- workaround douple substitution by mapping types/* to itself
   (see microsoft/TypeScript#41284)
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- "*" match seems to cause multiple path substitutions
microsoft/TypeScript#41284 that packge name prefix seems to resolve
- add types field which acts as main in TS
rvagg pushed a commit to multiformats/js-multiformats that referenced this issue Mar 31, 2021
- modify scripts to use newer tsc --bulid command
- generate types on prepare so linking to git dependency works
- workaround douple substitution by mapping types/* to itself
   (see microsoft/TypeScript#41284)
@andrewbranch andrewbranch removed this from the TypeScript 4.4.1 (RC) milestone Aug 31, 2021
@andrewbranch andrewbranch added this to the TypeScript 4.5.0 milestone Aug 31, 2021
@paulnelson2
Copy link

paulnelson2 commented Oct 22, 2021

Ran into this recently.

Also happens with directly adding "typesVersions" to package.json and using any wildcards. This may effect more people than the OP (which had package references and such), so here's an example repo if helpful:

https://github.com/paulnelson2/import-from-types-versions-package-bug-typescript

Details

With typesVersions:

{
  "typesVersions":  {
    "*": {
      "*": [
        "src/*"
      ]
    }
  }
}

and a file at (pkg)/src/fails/index.ts

Actual behavior

Fails trying to import "(pkg)/fails"

First it tries:
(pkg)/src/fails.ts (correctly substitutes "src/*" according to typesVersions)
Then tries to get the directory default export index.ts:
(pkg)/src/fails/src/index.ts (fails, as it repeats the substitution of "src/*")

Expected behavior:

Instead to try (pkg)/src/fails/index.ts to get the default directory export

Entire relevant traceResolution section:

======== Resolving module '@typescript-import-bug/lib/fails' from 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/src/main.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module '@typescript-import-bug/lib/fails' from 'node_modules' folder, target file type 'TypeScript'.
Directory 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/src/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/package.json' exists according to earlier cached lookups.
'package.json' has a 'typesVersions' entry '*' that matches compiler version '4.4.4', looking for a pattern to match module name 'fails'.
Module name 'fails', matched pattern '*'.
Trying substitution 'src/*', candidate module location: 'src/fails'.
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails.ts' does not exist.
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails.tsx' does not exist.
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails.d.ts' does not exist.
'package.json' does not have a 'typings' field.
'package.json' does not have a 'types' field.
'package.json' does not have a 'main' field.
'package.json' has a 'typesVersions' entry '*' that matches compiler version '4.4.4', looking for a pattern to match module name 'index'.
Module name 'index', matched pattern '*'.
Trying substitution 'src/*', candidate module location: 'src/index'.
Loading module as file / folder, candidate module location 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails/src/index', target file type 'TypeScript'.
Directory 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@types' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/node_modules/@types' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/Users/paulnelson/Documents/src/test/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/Users/paulnelson/Documents/src/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/Users/paulnelson/Documents/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/Users/paulnelson/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/Users/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Directory 'C:/node_modules' does not exist, skipping all lookups in it.
Scoped package detected, looking in 'typescript-import-bug__lib/fails'
Loading module '@typescript-import-bug/lib/fails' from 'node_modules' folder, target file type 'JavaScript'.
Directory 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/src/node_modules' does not exist, skipping all lookups in it.
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/package.json' exists according to earlier cached lookups.
'package.json' has a 'typesVersions' entry '*' that matches compiler version '4.4.4', looking for a pattern to match module name 'fails'.
Module name 'fails', matched pattern '*'.
Trying substitution 'src/*', candidate module location: 'src/fails'.
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails.js' does not exist.
File 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails.jsx' does not exist.
'package.json' does not have a 'main' field.
'package.json' has a 'typesVersions' entry '*' that matches compiler version '4.4.4', looking for a pattern to match module name 'index'.
Module name 'index', matched pattern '*'.
Trying substitution 'src/*', candidate module location: 'src/index'.
Loading module as file / folder, candidate module location 'C:/Users/paulnelson/Documents/src/test/import-from-types-versions-package-bug-typescript/main/node_modules/@typescript-import-bug/lib/src/fails/src/index', target file type 'JavaScript'.
Directory 'C:/Users/paulnelson/Documents/src/test/node_modules' does not exist, skipping all lookups in it.
Directory 'C:/Users/paulnelson/Documents/src/node_modules' does not exist, skipping all lookups in it.
Directory 'C:/Users/paulnelson/Documents/node_modules' does not exist, skipping all lookups in it.
Directory 'C:/Users/paulnelson/node_modules' does not exist, skipping all lookups in it.
Directory 'C:/Users/node_modules' does not exist, skipping all lookups in it.
Directory 'C:/node_modules' does not exist, skipping all lookups in it.
======== Module name '@typescript-import-bug/lib/fails' was not resolved. 

@pauldraper
Copy link

Workaround:

Instead of

{
  "typesVersions":  {
    "*": {
      "*": ["src/*"]
    }
  }
}

do

{
  "typesVersions": {
    "*": {
      "*": ["src/*"],
      "src/*": ["src/*"]
    }
  }
}

This turns the second expansion into a no-op.

@Twipped
Copy link

Twipped commented Sep 18, 2023

@pauldraper THANK YOU! This has been vexing me for months!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status. Rescheduled This issue was previously scheduled to an earlier milestone
Projects
None yet
Development

No branches or pull requests

7 participants