-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Description
Describe the problem
Svelte 5 runes are overall a much needed upgrade, but I think one area where they are a step back is the experience declaring props, especially when using TypeScript.
For example, this (Svelte 4 style):
export let initialValue: number | undefined;
export let onUpdate = (a: number) => {};
export let color = "test";
export let extra = false;
Is a much nicer developer experience than this, which is what we have now with runes:
interface Props {
initialValue: number | undefined,
onUpdate: (a: number) => void,
color: string,
extra: boolean
}
let {
initialValue,
onUpdate = (a) => {},
color = "test",
extra = false
}: Props = $props();
The repetition of property names and having to define a separate type make Svelte 5 a much more grating experience for those who depend on TypeScript.
This alone is really putting me off migrating to Svelte 5, which sucks because the new runes are such a massive improvement over stores.
Describe the proposed solution
I don't think bringing back export let
is a good idea as it's not very explicit and doesn't fit in now that we have runes.
I propose adding a singular version of the $props()
rune, which can be used on the right hand side of a let
assignment at the top level of a component's script. It would use the variable name on the left hand side as the property name, and can be given a default value.
The above code now turns into this:
let initialValue: number | undefined = $prop();
let onUpdate = $prop((a:number) => {});
let color = $prop("test")
let extra = $prop(false)
This eliminates the duplication of property names and eliminates the need for messy destructuring, especially in typescript where you'd need to declare a separate type or inline with the destructuring which hurts readability and maintainability.
The $bindable()
rune could also be expanded to have the same behaviour, where
let value: string = $bindable("Default Text")
would declare a bindable string property value
.
Importantly, we keep the $props()
rune for more complex use cases, but for simple components with a few properties I think this is much nicer from a DX perspective.
Importance
would make my life easier