Skip to content

Commit 53b9570

Browse files
committed
fix: don't replace rest props with $$props for excluded props
1 parent 30e2b23 commit 53b9570

File tree

7 files changed

+41
-2
lines changed

7 files changed

+41
-2
lines changed

.changeset/nervous-flies-laugh.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: don't replace rest props with `$$props` for excluded props

packages/svelte/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ export function VariableDeclarator(node, context) {
4646
: path.is_rest
4747
? 'rest_prop'
4848
: 'prop';
49+
if (rune === '$props' && binding.kind === 'rest_prop' && node.id.type === 'ObjectPattern') {
50+
const { properties } = node.id;
51+
/** @type {string[]} */
52+
const exclude_props = [];
53+
for (const property of properties) {
54+
if (property.type === 'RestElement') {
55+
continue;
56+
}
57+
const key = /** @type {Identifier | Literal & { value: string | number }} */ (
58+
property.key
59+
);
60+
exclude_props.push(key.type === 'Identifier' ? key.name : key.value.toString());
61+
}
62+
(binding.metadata ??= {}).exclude_props = exclude_props;
63+
}
4964
}
5065
}
5166

packages/svelte/src/compiler/phases/3-transform/client/visitors/Identifier.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ export function Identifier(node, context) {
3232
grand_parent?.type !== 'AssignmentExpression' &&
3333
grand_parent?.type !== 'UpdateExpression'
3434
) {
35-
return b.id('$$props');
35+
const key = /** @type {Identifier} */ (parent.property);
36+
37+
if (!binding.metadata?.exclude_props?.includes(key.name)) {
38+
return b.id('$$props');
39+
}
3640
}
3741
}
3842

packages/svelte/src/compiler/phases/scope.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export class Binding {
122122

123123
/**
124124
* Additional metadata, varies per binding type
125-
* @type {null | { inside_rest?: boolean; is_template_declaration?: boolean }}
125+
* @type {null | { inside_rest?: boolean; is_template_declaration?: boolean; exclude_props?: string[] }}
126126
*/
127127
metadata = null;
128128

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
async test({ assert, target }) {
5+
assert.equal(target.textContent, ' false');
6+
}
7+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
const { name, ...rest } = $props();
3+
</script>
4+
{rest.name} {'name' in rest}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<script>
2+
import Component from './component.svelte';
3+
</script>
4+
<Component name='world' />

0 commit comments

Comments
 (0)