Open Not-Jayden opened 11 months ago
For singular let width = $alias(dimensions.value.width)
, this should already work with $derived
, so it could "just" be a case of allowing multiple derived signals from one $derived
rune by destructing, which would certainly be a welcome utility
For singular
let width = $alias(dimensions.value.width)
, this should already work with$derived
, so it could "just" be a case of allowing multiple derived signals from one$derived
rune by destructing, which would certainly be a welcome utility
It's not quite the same. The distinction is essentially:
$derived()
calculates an immutable value based on its dependencies, ensuring it stays in sync with the reactive values.$alias()
creates a direct reference to the reactive property, allowing you to both read and modify it directly.So for:
let width = $derived(dimensions.value.width);
While this keeps width in sync with the reactive value like $alias()
would, you cannot assign to it at all. Using $alias()
, width
acts as a shorthand direct reference to dimensions.value.width
, allowing you to directly read and modify it.
This would be a nice feature. I am going to add one more case for a similar idea, @alias
. This would be very useful in nested loops for example:
let filters = $state({
attack: {
combos: { active: false, input: {comb1: false, comb2: false}, type: InputType.Grid },
hitType: {
active: false,
input: {"Perfect": false, "Good": false, "Bad": false},
},
effect: {
active: false,
input: {...},
},
},
{#each Object.entries(filters) as section, val}
{...}
{#each Object.entries(val) as [name, val]}
{...}
{#each Object.keys(val.input) as input}
{...}
bind:checked={filters[section][name].input[input]}
bind:checked={filters[section][name].active}
{...}
instead I could just do
{#each ...}
{#each ....}
{@alias filter = filters[section][name]}
bind:checked={filter.input[input]}
bind:checked={filter.active}
{...}
Describe the problem
Svelte 5's reactivity introduces a requirement for at least one layer deep of nesting when reactive state is defined outside of the top level of a component, and in many cases, will likely have even deeper nested reactive properties. The necessity for nested property access adds a level of verbosity which can make the code less readable and harder to manage.
e.g.
Describe the proposed solution
Introduce a new rune,
$alias()
, which enables the creation of new variables from reactive properties and the destructuring of nested reactive properties while retaining reactivity/object property reference. The$alias()
rune essentially instructs the compiler to replace variable references with the expanded property access wherever the aliased or destructured variable is referenced, ensuring the reactivity of the original properties is maintained.The Svelte compiler ideally should issue a warning on attempts to assign to referenced properties that don't have setters, as this is a limitation of assigning primitive values in javascript.
e.g. the example above could instead be writted as:
If desired, you should also be able to create variables using variable assignment instead of destructuring as well. i.e.
Alternatives considered
Some alternative naming has been suggested such as
$bind()
,$link()
,$expose()
, or$bridge()
.Otherwise the alternative is we continue to require always directly accessing nested properties.
Importance
nice to have