From 9071bd4e47bbf1c87613f77889973441b13ce297 Mon Sep 17 00:00:00 2001 From: ComputerGuy <63362464+Ocean-OS@users.noreply.github.com> Date: Wed, 15 Oct 2025 21:13:09 -0700 Subject: [PATCH 1/2] fix: allow keyed `{#each ...}` without `as` --- .changeset/olive-tomatoes-ring.md | 5 +++++ .../phases/3-transform/client/visitors/EachBlock.js | 13 ++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 .changeset/olive-tomatoes-ring.md diff --git a/.changeset/olive-tomatoes-ring.md b/.changeset/olive-tomatoes-ring.md new file mode 100644 index 000000000000..0aba6fe33cad --- /dev/null +++ b/.changeset/olive-tomatoes-ring.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: allow keyed `{#each ...}` without `as` diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js index 225a4f617c50..95cdc0134cb5 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js @@ -298,12 +298,19 @@ export function EachBlock(node, context) { let key_function = b.id('$.index'); if (node.metadata.keyed) { - const pattern = /** @type {Pattern} */ (node.context); // can only be keyed when a context is provided + const pattern = node.context; const expression = /** @type {Expression} */ ( context.visit(/** @type {Expression} */ (node.key), key_state) ); - - key_function = b.arrow(key_uses_index ? [pattern, index] : [pattern], expression); + /** @type {Pattern[]} */ + const args = []; + if (pattern) { + args.push(pattern); + } + if (key_uses_index) { + args.push(index); + } + key_function = b.arrow(args, expression); } if (node.index && each_node_meta.contains_group_binding) { From 08a24f1abeeaefaa257b3762e6d61085419e6b7f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 16 Oct 2025 10:08:50 -0400 Subject: [PATCH 2/2] fix, add test --- .../phases/3-transform/client/visitors/EachBlock.js | 13 ++++--------- .../samples/each-without-as-keyed/_config.js | 13 +++++++++++++ .../samples/each-without-as-keyed/main.svelte | 11 +++++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/main.svelte diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js index 95cdc0134cb5..9064db311b66 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js @@ -298,18 +298,13 @@ export function EachBlock(node, context) { let key_function = b.id('$.index'); if (node.metadata.keyed) { - const pattern = node.context; const expression = /** @type {Expression} */ ( context.visit(/** @type {Expression} */ (node.key), key_state) ); - /** @type {Pattern[]} */ - const args = []; - if (pattern) { - args.push(pattern); - } - if (key_uses_index) { - args.push(index); - } + + const args = [node.context ?? b.id('$$')]; + if (key_uses_index) args.push(index); + key_function = b.arrow(args, expression); } diff --git a/packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/_config.js b/packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/_config.js new file mode 100644 index 000000000000..82707da72e00 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/_config.js @@ -0,0 +1,13 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + html: `

3

2

1

`, + + async test({ target, assert }) { + const [button] = target.querySelectorAll('button'); + + flushSync(() => button.click()); + assert.htmlEqual(target.innerHTML, `

1

2

3

`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/main.svelte b/packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/main.svelte new file mode 100644 index 000000000000..4276c2a36bcd --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/each-without-as-keyed/main.svelte @@ -0,0 +1,11 @@ + + + + +{#each items, i (items[i].id)} +

{items[i].id}

+{/each}