ReviewOS

stacks/dtsx

Named imports from 'typescript' break the extractor under TypeScript 7

#3108
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Split out of #3107, which I originally filed with this as the headline. The truncation reported there turned out to be unrelated and is fixed; this part is real and still open, so it gets its own issue rather than riding along.

Summary

TypeScript 7 is a Go port whose npm package exports only version and versionMajorMinor. Five modules import compiler-API symbols by name, and a named import of a missing export is a hard link error — the module cannot be loaded at all:

extractor/cache.ts, extractor/helpers.ts, extractor/index.ts,
extractor/declarations.ts, extractor/builders.ts
$ bun -e "import('./packages/dtsx/src/extractor/cache.ts')"
SyntaxError: Export named 'createSourceFile' not found in module
  ~/.bun/install/cache/typescript@7.0.2@@@1/lib/version.cjs

Why the package still appears to work

checker.ts, parallel-processor.ts, utils.ts and circular.ts use a default import (import ts from 'typescript'). Under Bun's CJS interop that yields an object whose members are just undefined, so those modules link fine and only fail if they actually call one. And import('@stacksjs/dtsx') / processSource never pull the extractor cache in — so the failure is invisible until something reaches an AST path.

That is arguably worse than a clean break: ts.createSourceFile, ts.createProgram, ts.forEachChild, ts.sys, ts.readConfigFile and ts.parseJsonConfigFileContent are all undefined at runtime with no error at import time.

Why the declared range doesn't protect it

packages/dtsx/package.json:

"peerDependencies": { "typescript": ">=5.9.3" },
"dependencies": { "typescript": "^6.0.2", "oxc-parser": "^0.121.0" }

The peer range >=5.9.3 says 7.x is supported, and it isn't. In a workspace that also depends on TypeScript — stacksjs/stx declares ^7.0.2 — the hoisted copy is what an unscoped import('typescript') resolves to, and it wins over the declared dependency.

Options, roughly in increasing order of effort

  1. Make the peer range honest — >=5.9.3 <7. One line; converts a silent runtime degradation into an install-time error. Doesn't make dtsx work on 7, but stops it claiming to.
  2. Guard the API surface — check for createSourceFile at load and fail with a message naming the version, instead of undefined is not a function somewhere deep.
  3. Move off the compiler API — oxc-parser is already a declared dependency and is imported nowhere in packages/dtsx/src. That's the durable fix if TS 7 is where the ecosystem is going, since the JS compiler API isn't coming back in a 7.x patch.

Happy to take (1) and (2) if they're wanted — (3) is a real rewrite across ~25 API symbols and seems like a maintainer call.

Sign in to comment on this issue.