fix: don't replace rest props with `$$props` for excluded props (#16898)

Closes #16895
pull/16910/head
ComputerGuy 2 days ago committed by GitHub
parent fc39f2ed0d
commit 303750a124
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't replace rest props with `$$props` for excluded props

@ -46,6 +46,21 @@ export function VariableDeclarator(node, context) {
: path.is_rest
? 'rest_prop'
: 'prop';
if (rune === '$props' && binding.kind === 'rest_prop' && node.id.type === 'ObjectPattern') {
const { properties } = node.id;
/** @type {string[]} */
const exclude_props = [];
for (const property of properties) {
if (property.type === 'RestElement') {
continue;
}
const key = /** @type {Identifier | Literal & { value: string | number }} */ (
property.key
);
exclude_props.push(key.type === 'Identifier' ? key.name : key.value.toString());
}
(binding.metadata ??= {}).exclude_props = exclude_props;
}
}
}

@ -32,7 +32,11 @@ export function Identifier(node, context) {
grand_parent?.type !== 'AssignmentExpression' &&
grand_parent?.type !== 'UpdateExpression'
) {
return b.id('$$props');
const key = /** @type {Identifier} */ (parent.property);
if (!binding.metadata?.exclude_props?.includes(key.name)) {
return b.id('$$props');
}
}
}

@ -122,7 +122,7 @@ export class Binding {
/**
* Additional metadata, varies per binding type
* @type {null | { inside_rest?: boolean; is_template_declaration?: boolean }}
* @type {null | { inside_rest?: boolean; is_template_declaration?: boolean; exclude_props?: string[] }}
*/
metadata = null;

@ -0,0 +1,7 @@
import { test } from '../../test';
export default test({
async test({ assert, target }) {
assert.equal(target.textContent, ' false');
}
});

@ -0,0 +1,4 @@
<script>
const { name, ...rest } = $props();
</script>
{rest.name} {'name' in rest}

@ -0,0 +1,4 @@
<script>
import Component from './component.svelte';
</script>
<Component name='world' />
Loading…
Cancel
Save