Skip to content

fix: split types per entrypoint for alias installs#17650

Draft
RazinShafayet2007 wants to merge 2 commits intosveltejs:mainfrom
RazinShafayet2007:fix/alias-subpath-dts
Draft

fix: split types per entrypoint for alias installs#17650
RazinShafayet2007 wants to merge 2 commits intosveltejs:mainfrom
RazinShafayet2007:fix/alias-subpath-dts

Conversation

@RazinShafayet2007
Copy link
Contributor

Fixes #17520

This PR fixes TypeScript type resolution when Svelte is installed under a package alias. Previously, Svelte relied on a single ambient types/index.d.ts with hard‑coded module names like svelte/compiler. When the package is aliased, those ambient declarations don’t match the installed specifiers (e.g. svelte5/compiler), so TypeScript reports “is not a module.” This also breaks tooling like tsup, tsdown, and other DTS bundlers.

To fix this, types are now aligned with the export map by generating per‑entrypoint .d.ts files (e.g. types/compiler.d.ts, types/store.d.ts, etc.) and wiring exports.types to those files. This makes TypeScript resolve types via the entrypoint file path, which is agnostic to the package name. Core type identities are centralized in types/shared.d.ts, and global/ambient declarations are isolated in types/ambient.d.ts to avoid cross‑module conflicts.

With this change, aliased installs resolve types correctly, subpath imports no longer error, and downstream tooling can bundle or analyze Svelte types reliably. Non‑aliased installs remain unchanged.


Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

@changeset-bot
Copy link

changeset-bot bot commented Feb 7, 2026

🦋 Changeset detected

Latest commit: 447a77c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@RazinShafayet2007 RazinShafayet2007 had a problem deploying to Publish pkg.pr.new (external contributors) February 7, 2026 17:29 — with GitHub Actions Failure
@RazinShafayet2007 RazinShafayet2007 had a problem deploying to Publish pkg.pr.new (external contributors) February 7, 2026 17:45 — with GitHub Actions Failure
@Rich-Harris
Copy link
Member

Thank you. The reason we do things this way is because not all TypeScript configurations support subpath resolution; we found that the easiest way to make it work everywhere was with declare module, even though it's colouring outside the lines a bit. Changing to this approach would be a breaking change for at least some people, and so unfortunately I think it's a non-starter at least until Svelte 6, at which point we would have to re-evaluate whether it's safe to rely on people having a modern moduleResolution configuration. Unless you have an idea for maintaining compatibility?

Additionally, why does every entrypoint re-export from shared.ts? That doesn't seem right.

@Rich-Harris Rich-Harris marked this pull request as draft February 10, 2026 15:44
@RazinShafayet2007
Copy link
Contributor Author

Thanks. That makes sense. However, I don’t see a clean compatibility‑preserving fix for arbitrary alias names without relying on modern moduleResolution or user‑side paths. The only maybe idea would be leaning on root‑level shims plus typesVersions, but I’m not confident it works reliably across configs. The package can’t know the alias name at publish time, so declare module 'svelte/*' can’t cover svelte5/*. Root‑level shims already exist (e.g. action.d.ts, store.d.ts, compiler.d.ts) to support classic resolution, but they don’t solve the unknown‑alias problem. On the shared re‑exports, that was to keep type identity stable. Without a single canonical source, Component/Brand types from different entrypoints become incompatible. I agree it’s not ideal but it avoids type‑identity breakage.

@Rich-Harris
Copy link
Member

Without a single canonical source

Isn't it sufficient to import them from the same place? Why do they also need to be exported?

@RazinShafayet2007 RazinShafayet2007 had a problem deploying to Publish pkg.pr.new (external contributors) February 11, 2026 04:43 — with GitHub Actions Failure
@RazinShafayet2007
Copy link
Contributor Author

Isn't it sufficient to import them from the same place? Why do they also need to be exported?

You’re right that a single canonical import source is enough for internal references. I added per-entrypoint export * from ./shared' as a conservative compatibility guard after splitting the monolithic declarations into per-entrypoint files, so consumers/tooling that might have relied on broad symbol visibility wouldn’t break unexpectedly. I removed shared re-exports from subpath entrypoints; types/index.d.ts remains the only public shared re-export.

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.

TypeScript types break when aliasing the package

2 participants