fix: remove bindable prop validation (#14946)

pull/14953/head
Rich Harris 3 days ago committed by GitHub
parent 9b71eea35d
commit ce4f9722da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: remove bindable prop validation

@ -299,28 +299,6 @@ export function client_component(analysis, options) {
(binding.kind === 'prop' || binding.kind === 'bindable_prop') && !name.startsWith('$$')
);
if (dev && analysis.runes) {
const exports = analysis.exports.map(({ name, alias }) => b.literal(alias ?? name));
/** @type {ESTree.Literal[]} */
const bindable = [];
for (const [name, binding] of properties) {
if (binding.kind === 'bindable_prop') {
bindable.push(b.literal(binding.prop_alias ?? name));
}
}
instance.body.unshift(
b.stmt(
b.call(
'$.validate_prop_bindings',
b.id('$$props'),
b.array(bindable),
b.array(exports),
b.id(`${analysis.name}`)
)
)
);
}
if (analysis.accessors) {
for (const [name, binding] of properties) {
const key = binding.prop_alias ?? name;

@ -150,7 +150,7 @@ export {
setContext,
hasContext
} from './runtime.js';
export { validate_binding, validate_each_keys, validate_prop_bindings } from './validate.js';
export { validate_binding, validate_each_keys } from './validate.js';
export { raf } from './timing.js';
export { proxy } from './proxy.js';
export { create_custom_element } from './dom/elements/custom-element.js';

@ -297,8 +297,10 @@ export function prop(props, key, flags, fallback) {
var is_entry_props = STATE_SYMBOL in props || LEGACY_PROPS in props;
var setter =
get_descriptor(props, key)?.set ??
(is_entry_props && bindable && key in props ? (v) => (props[key] = v) : undefined);
(bindable &&
(get_descriptor(props, key)?.set ??
(is_entry_props && key in props && ((v) => (props[key] = v))))) ||
undefined;
var fallback_value = /** @type {V} */ (fallback);
var fallback_dirty = true;

@ -1,5 +1,5 @@
import { dev_current_component_function } from './runtime.js';
import { get_descriptor, is_array } from '../shared/utils.js';
import { is_array } from '../shared/utils.js';
import * as e from './errors.js';
import { FILENAME } from '../../constants.js';
import { render_effect } from './reactivity/effects.js';
@ -38,29 +38,6 @@ export function validate_each_keys(collection, key_fn) {
});
}
/**
* @param {Record<string, any>} $$props
* @param {string[]} bindable
* @param {string[]} exports
* @param {Function & { [FILENAME]: string }} component
*/
export function validate_prop_bindings($$props, bindable, exports, component) {
for (const key in $$props) {
var setter = get_descriptor($$props, key)?.set;
var name = component.name;
if (setter) {
if (exports.includes(key) && !bindable.includes(key)) {
e.bind_invalid_export(component[FILENAME], key, name);
}
if (!bindable.includes(key)) {
e.bind_not_bindable(key, component[FILENAME], name);
}
}
}
}
/**
* @param {string} binding
* @param {() => Record<string, any>} get_object

@ -1,10 +0,0 @@
import { test } from '../../test';
export default test({
compileOptions: {
dev: true // to ensure we we catch the error
},
error:
'bind_invalid_export\n' +
'Component counter/index.svelte has an export named `increment` that a consumer component is trying to access using `bind:increment`, which is disallowed. Instead, use `bind:this` (e.g. `<Counter bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.increment`)'
});

@ -1,8 +0,0 @@
<script>
let count = $state(0);
export function increment() {
count++;
}
</script>
{count}

@ -1,7 +0,0 @@
<script>
import Counter from './counter/index.svelte';
let increment;
</script>
<Counter bind:increment={increment} />
<button onclick={increment}>increment</button>

@ -1,5 +0,0 @@
<script>
let { ...rest } = $props();
</script>
{rest.count}

@ -1,13 +0,0 @@
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
html: '0',
error:
'bind_not_bindable\n' +
'A component is attempting to bind to a non-bindable property `count` belonging to Counter.svelte (i.e. `<Counter bind:count={...}>`). To mark a property as bindable: `let { count = $bindable() } = $props()`'
});

@ -1,7 +0,0 @@
<script>
import Counter from './Counter.svelte';
let count = $state(0);
</script>
<Counter bind:count />

@ -1,5 +0,0 @@
<script>
let { count } = $props();
</script>
{count}

@ -1,13 +0,0 @@
import { test } from '../../test';
export default test({
compileOptions: {
dev: true
},
html: '0',
error:
'bind_not_bindable\n' +
'A component is attempting to bind to a non-bindable property `count` belonging to Counter.svelte (i.e. `<Counter bind:count={...}>`). To mark a property as bindable: `let { count = $bindable() } = $props()`'
});

@ -1,7 +0,0 @@
<script>
import Counter from './Counter.svelte';
let count = $state(0);
</script>
<Counter bind:count />
Loading…
Cancel
Save