breaking: make non-bindable props read-only

readonly-props
Rich Harris 3 months ago
parent 363a5418e6
commit 73a3895dea

@ -0,0 +1,5 @@
---
'svelte': patch
---
breaking: make non-bindable props read-only

@ -6,6 +6,8 @@
> Cannot assign to %thing%
> Cannot assign to %thing%. %suggestion%
## constant_binding
> Cannot bind to %thing%

@ -69,13 +69,14 @@ export function bindable_invalid_location(node) {
}
/**
* Cannot assign to %thing%
* Cannot assign to %thing%. %suggestion%
* @param {null | number | NodeLike} node
* @param {string} thing
* @param {string | undefined | null} [suggestion]
* @returns {never}
*/
export function constant_assignment(node, thing) {
e(node, "constant_assignment", `Cannot assign to ${thing}`);
export function constant_assignment(node, thing, suggestion) {
e(node, "constant_assignment", suggestion ? `Cannot assign to ${thing}. ${suggestion}` : `Cannot assign to ${thing}`);
}
/**

@ -23,6 +23,14 @@ export function validate_assignment(node, argument, state) {
e.constant_assignment(node, 'derived state');
}
if (binding?.kind === 'prop') {
e.constant_assignment(
node,
'a non-bindable prop',
'Use `$state.link(...)` to create a local copy of the value'
);
}
if (binding?.kind === 'each') {
e.each_item_invalid_assignment(node);
}

@ -14,7 +14,3 @@
<button onclick={() => (non_bindable.count += 1)}>
mutate: {non_bindable.count}
</button>
<button onclick={() => (non_bindable = { count: non_bindable.count + 1 })}>
reassign: {non_bindable.count}
</button>

@ -6,11 +6,10 @@ export default test({
<button>mutate: 0</button>
<button>reassign: 0</button>
<button>mutate: 0</button>
<button>reassign: 0</button>
`,
async test({ assert, target }) {
const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button');
const [btn1, btn2, btn3] = target.querySelectorAll('button');
flushSync(() => {
btn1?.click();
@ -22,7 +21,6 @@ export default test({
<button>mutate: 1</button>
<button>reassign: 1</button>
<button>mutate: 0</button>
<button>reassign: 0</button>
`
);
@ -36,7 +34,6 @@ export default test({
<button>mutate: 2</button>
<button>reassign: 2</button>
<button>mutate: 0</button>
<button>reassign: 0</button>
`
);
@ -50,7 +47,6 @@ export default test({
<button>mutate: 3</button>
<button>reassign: 3</button>
<button>mutate: 0</button>
<button>reassign: 0</button>
`
);
@ -64,35 +60,6 @@ export default test({
<button>mutate: 3</button>
<button>reassign: 3</button>
<button>mutate: 0</button>
<button>reassign: 0</button>
`
);
flushSync(() => {
btn4?.click();
});
assert.htmlEqual(
target.innerHTML,
`
<button>mutate: 3</button>
<button>reassign: 3</button>
<button>mutate: 2</button>
<button>reassign: 2</button>
`
);
flushSync(() => {
btn3?.click();
});
assert.htmlEqual(
target.innerHTML,
`
<button>mutate: 3</button>
<button>reassign: 3</button>
<button>mutate: 2</button>
<button>reassign: 2</button>
`
);
}

Loading…
Cancel
Save