refactor(tsc): defer web-platform globals to lib.dom in deno libs#35639
Merged
Conversation
Wrap each web-platform `declare var` in cli/tsc/dts/lib.deno_*.d.ts that
overlaps with @types/node in a
`typeof globalThis extends { document: any; Name: infer T } ? T : <original>`
conditional, so each global re-exports lib.dom's type when lib.dom is loaded
(precedence dom > deno) and lets stock @types/node's own
`typeof globalThis extends { onmessage: any; Name: infer T }` probe defer to
Deno's declaration otherwise (precedence deno > node).
Behaviour-neutral under the current forked tsc: a Deno file's globalThis has no
`document`, so the conditional always yields the original Deno type. This is
groundwork for removing the fork's dual node/deno global symbol-table split.
Generated by tools/apply_web_globals_deferral.ts (derives the overlap set from
TYPES_NODE_IGNORABLE_NAMES).
bartlomieju
added a commit
that referenced
this pull request
Jul 8, 2026
This drops Deno's forked TypeScript compiler and runs on stock `[email protected]` from npm (the exact version the fork was based on). The forked `cli/tsc/00_typescript.js` and its ~466-line patch set are removed, along with the five `ts.deno.*` host hooks the fork exposed (`setIsNodeSourceFileCallback`, `setNodeOnlyGlobalNames`, `setTypesNodeIgnorableNames`, and the LSP span callbacks). Forking tsc has meant a manual re-port of the patch set and a hand-rebuilt 9 MB bundle on every upgrade; on stock TypeScript an upgrade becomes a version bump. The fork's load-bearing patch was a dual node/deno global symbol table in the checker. That is replaced by a pure `.d.ts` mechanism: Deno's libs declare the marker globals (`onmessage`/`onabort`/`ReportingObserver`) that stock `@types/node` probes for, so `@types/node` defers its web-platform globals to Deno's exactly as it defers to `lib.dom`, and everything resolves against a single global table. This builds on the prep PRs already merged: the deferral transform (#35639), the `PerformanceObserver` types (#35640), and single `@types/node` loading (#35641). It also carries the `URLPattern` concession (`@types/node` declares it unconditionally, so Deno keeps only the interface) and tightens `import.meta.dirname`/`filename` to required `string` to match `@types/node`. This is a breaking change and targets Deno 3. Five `check` specs are temporarily disabled with `ignore: true` and a comment pointing at their follow-ups: `check_workspace` and the marker interaction, the `export =` declaration-file case, per-member `jsxImportSource` (`jsx_import_source_different_per_member`), and transitive `@types/node` (`express_with_koa`, re-enabled by #35871). The LSP runs on the same stock compiler; its dedicated verification is still pending. See #35621 for the full investigation and plan. Fixes #33012
magurotuna
added a commit
to denoland/deno_graph
that referenced
this pull request
Jul 9, 2026
Refreshes the ecosystem snapshots that are currently red on CI (surfaced on #658, 2026-07-09). Regenerated with `UPDATE=1 cargo test --test ecosystem <spec>` against canary `4064da2bee25c414481dc7985e474b62da497066`, and verified green without `UPDATE` afterwards. Specs refreshed: - `bureaudouble/[email protected]` - `ipinfo/[email protected]` … `1.0.7` - `mebus/[email protected]`, `@1.0.2` All are **canary drift**, not registry drift (an earlier attribution in #659 was wrong — see the correction comment there): - **`bureaudouble/[email protected]`** — bisected to denoland/deno#35639 ("defer web-platform globals to lib.dom in deno libs"): the error set (TS2304/TS2552) is unchanged, but the TS2552 related-information snippet quotes `CloseEvent`'s declaration, whose text changed with the lib restructuring (`declare var CloseEvent: { ... }` → `typeof globalThis extends ...` form). - **`ipinfo/client` and `mebus/mebus`** — `TYPE CHECK FAILED` → `PASSED` from the Deno 2.8 → 2.9 transition (npm types resolution improved: `mebus` no longer errors on `[email protected]`'s default import, TS1192; `ipinfo` no longer errors on the `puppeteer` namespace, TS2503). The minimal repro fails on Deno 2.8.3 (matching the old snapshots) and passes on 2.9.1+. The main ecosystem workflow has in fact been red for these since 2026-06-22 (last green: 2026-06-10) — it went unnoticed because it isn't a required check. Note: beyond the snapshot refresh, the process problem is that the ecosystem workflow stayed red on main for weeks without anyone noticing — #659's correction comment discusses that; this PR just brings the snapshots in line with what CI observes today. Closes #659
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reshapes the web-platform
declare vardeclarations in Deno's bundledlib.deno_*.d.tsso each global re-exportslib.dom's type whenlib.domispresent and otherwise keeps Deno's own type, using the same conditional-deferral
pattern
@types/nodealready uses to coexist withlib.dom:documentis a DOM-exclusive marker (Deno's own globals never declare it), so ona normal Deno program the conditional always resolves to Deno's own type. This is
behaviour-neutral today: the full
checkspec suite passes unchanged. It onlytakes effect when
lib.domis also loaded, where each global now defers to theDOM definition instead of colliding with it.
The motivation is to let Deno's libs coexist with a single global symbol table
(stock TypeScript and
@types/node) rather than relying on the bundledcompiler's dual node/deno global tables. This is the first, behaviour-neutral
step of that work; nothing about the default Deno experience changes.
The change is generated and reproducible via
tools/apply_web_globals_deferral.ts,which derives the overlapping name set from
TYPES_NODE_IGNORABLE_NAMESandrewrites the affected type nodes in place so comments and formatting are
preserved.
Part of the broader effort to drop Deno's forked TypeScript; see #35621 for context and the overall plan.