Skip to content

fix(typescript-vfs): resolve lib dir via getDefaultLibFilePath so re-export wrappers (@typescript/typescript6) work - #3646

Draft
Andrea (andrepav1) wants to merge 1 commit into
microsoft:v2from
andrepav1:fix/vfs-lib-dir-reexport-wrapper
Draft

fix(typescript-vfs): resolve lib dir via getDefaultLibFilePath so re-export wrappers (@typescript/typescript6) work#3646
Andrea (andrepav1) wants to merge 1 commit into
microsoft:v2from
andrepav1:fix/vfs-lib-dir-reexport-wrapper

Conversation

@andrepav1

Copy link
Copy Markdown

Problem

createDefaultMapFromNodeModules finds the bundled lib.*.d.ts via path.dirname(require.resolve("typescript")). require.resolve returns the resolved package's entry file, so for a re-export wrapper the directory it points at contains no lib files.

This breaks with the official TypeScript 7.0 side-by-side package @typescript/typescript6 (npm i -D typescript@npm:@typescript/typescript6), whose entry is module.exports = require("@typescript/old"). The real lib.*.d.ts live in the nested @typescript/old/lib/, so the default map is built without the stdlib and the VFS later throws:

TSVFS: A request was made for .../@typescript/typescript6/lib/lib.es2020.d.ts
but there wasn't a file found in the file map.

Any tool that builds a program through createDefaultMapFromNodeModules (e.g. @ark/attest) fails on a project using the TS 7 side-by-side setup.

Fix

Derive the lib directory from the compiler's own getDefaultLibFilePath, which resolves from the executing file path and so follows the re-export to where the stdlib actually lives, instead of require.resolve:

const ts = _ts ?? (require('typescript') as typeof import('typescript'));
const libDir = tsLibDirectory || path.dirname(ts.getDefaultLibFilePath(_compilerOptions));
  • Preserves the existing tsLibDirectory override.
  • No caller change needed — callers like @ark/attest invoke createDefaultMapFromNodeModules(compilerOptions) with neither _ts nor tsLibDirectory.
  • Works for both plain installs and aliased / wrapped installs.

Notes

  • createFSBackedSystem further down has the same path.dirname(require.resolve("typescript")) pattern; happy to fix it here too — left out to keep the change focused on the reported path.
  • Verified against @typescript/typescript6@6.0.2: getDefaultLibFilePath returns the @typescript/old (typescript@6.0.3) lib dir with all 108 lib.*.d.ts.
  • Same layout concern as the closed docs attempt docs(typescript6): note @typescript/old layout for path-based tooling #3620.

…export wrappers work

createDefaultMapFromNodeModules located lib.*.d.ts via path.dirname(require.resolve("typescript")), the resolved entry file's directory. For the official @typescript/typescript6 TS 7 side-by-side wrapper (whose entry re-exports @typescript/old) that directory has no lib files, so the default map was built without the stdlib and the VFS later threw. Derive the lib dir from the compiler's getDefaultLibFilePath, which follows the re-export.
@andrepav1
Andrea (andrepav1) force-pushed the fix/vfs-lib-dir-reexport-wrapper branch from d4fb442 to e2ab0e7 Compare September 3, 2026 21:37

// Resolve the lib dir from the compiler, which follows re-export wrappers (e.g. @typescript/typescript6)
// to the real stdlib; require.resolve would point at the wrapper's own lib/, which has no lib.*.d.ts.
const ts = _ts ?? (require("typescript") as typeof import("typescript"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this break browser uses?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants