feat: allow declarations in the template#18282
Conversation
Allows `{let/var/const/function ...}` declarations in all places where we already allow `{@const ...}` (which will eventually get deprecated in favor of this new feature).
🦋 Changeset detectedLatest commit: a283cf7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
|
I don't remember where I made this comment previously, but I don't think we should allow |
|
Mhm yeah it might be better now that I'm thinking about it. Main reason that we can't guarantee the scope of the surrounding block. E.g. the if block scope might be different for if-else-chains (either porous because real if-else or not because functions) depending on non-obvious rules. |
…ot guarantee that the same scoping rules always apply due to our optimizations, and it is kinda harder to reason about anyway + you can model everything with const/let
|
I think we should disallow semicolons: #18312. Other than that, and the (I'm pretty sure?) leftover |
I think we should disallow semicolons in declaration tags, because syntactic ambiguity is always unfortunate and `;}` (the little-used 'winking grinch' emoticon) looks pretty ugly. We should _definitely_ remove it from code generated with `print`, even though it unfortunately requires us to duplicate some of the logic in the `ts` printer.
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## svelte@5.56.0 ### Minor Changes - feat: allow declarations in the template ([#18282](#18282)) ### Patch Changes - perf: use `createElement` instead of `createElementNS` for HTML elements ([#18262](#18262)) - perf: store `current_sources` as a `Set` for O(1) membership checks ([#18278](#18278)) - perf: deduplicate identical hoisted templates within a component ([#18320](#18320)) - perf: hoist `rest_props` exclude list as a module-scope `Set` ([#18252](#18252)) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Add support for Svelte 5 declaration tags — `{const x = expr}` and
`{let x = expr}` used directly in markup (no `@` prefix), introduced in
Svelte 5.56 (sveltejs/svelte#18282).
- AST: new `DeclarationTag` node + `DeclarationKind { Const, Let }`,
mirroring the existing `ConstTag`.
- Parser: disambiguate `{const ...}`/`{let ...}` from ordinary
expressions in `parse_expression_tag` via `peek_declaration_kind`
(no lexer change — `const` already fires standalone via logos
max-munch; `let` is matched by Ident text). Supports identifier,
object `{a, b}`, and array `[a, b]`/`[head, ...tail]` targets
(the latter via a `Text`-token-starting-with-`[` peek, since the
lexer has no dedicated `LBracket`). Semicolons inside the tag are
reported as errors. `{@const}` and `{constFoo}`/`{x}`/`{let}` are
unaffected.
- Transformer: emit `const x = y;` / `let x = y;` in place, with a
source mapping anchored to the post-keyword declaration text,
matching the language-tools svelte2tsx reference.
- Diagnostics: declaration tags stay in the no-op group so runes in
initializers (e.g. `{let s = $state(0)}`) are not falsely flagged.
Tests: 13 parser unit tests (both kinds, whitespace, object/array
destructuring, disambiguation, `{@const}` regression, semicolon ban,
in-`#each`), 4 parser + 6 transformer snapshots (incl. samples adapted
from language-tools ts-declaration-tag.v5 / declaration-tag-async.v5),
and corpus fixtures covering if/each/await/snippet/element/shadowing,
TS annotations + `$state`, and a must-not-panic invalid fixture.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Allows
{let/const ...}declarations in all places (and more) where we already allow{@const ...}(which will eventually get deprecated in favor of this new feature).Closes: #16490
Companion PRs: