Replies: 4 comments 1 reply
|
Hii @th0rgall, In Svelte 5, to mix inferred defaults with explicit types, use interface ExplicitProps { accept: string | string[] }
let {
accept,
disabled = false,
maxSize = Infinity,
minSize = 0,
multiple = true,
preventDropOnDocument = true,
noClick = false,
noKeyboard = false,
noDrag = false,
noDragEventsBubbling = false,
containerClasses = '',
containerStyles = '',
disableDefaultStyles = false,
name = ''
}: Partial<ExplicitProps> & typeof $props() = $props();
✅ Rule of thumb: use explicit types for required props, defaults handle inference for the rest. If this answer solved all your doubts, please mark it as solved. If not, please tell me your doubt. |
|
@th0rgall yes, svelte 5 is unavoidably more verbose here. this is a known trade-off of the runes design and it's working as intended. why it works this way: in svelte 4, each when you write a few things that were considered and rejected:
the cleanest pattern for your case: interface Props {
accept: string | string[];
disabled?: boolean;
maxSize?: number;
minSize?: number;
multiple?: boolean;
}
let {
accept,
disabled = false,
maxSize = Infinity,
minSize = 0,
multiple = true,
}: Props = $props();for components with many optional props that share patterns, you can use intersection types to reduce repetition: type Validatable = { maxSize?: number; minSize?: number };
type Props = Validatable & {
accept: string | string[];
disabled?: boolean;
multiple?: boolean;
};ref: svelte $props docs | discussion #10690 (brunnerh's explanation) | TS #29526 (partial destructuring types) |
|
Short answer: no — under What you can do is reduce the boilerplate, not eliminate it. Since every prop with a fallback should be optional anyway, mark those interface Props {
accept: string | string[]; // required, no default
disabled?: boolean;
maxSize?: number;
minSize?: number;
multiple?: boolean;
}
let {
accept,
disabled = false,
maxSize = Infinity,
minSize = 0,
multiple = true,
}: Props = $props();A couple of notes:
The previously suggested So for this case Svelte 5 is a bit more verbose by design — explicit annotation on the full |
|
Since everyone is giving AI answers I figured I could give a genuine one. I think the workaround you mentioned is what you need to do. Personally I think it only makes your component inputs clearer when you explicitly state the props as an interface. So unless typescript has an update, or svelte some day allows you to call the let { required }: {required: boolean} = $props()
let { optionalA = true, optionalB = "boba"} = $props()you'll probably have to explicitly type your optional fields |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hello, I'm doing a sizeable Svelte 4 -> 5 migration, and I've encountered some components which have many props with default values.
In Svelte 4, Svelte/TS could infer the types of the props using their default values. For those props that did not have a default value, it was possible to explicitly specify their type while keeping inference for the rest.
I haven't found a way to do this in Svelte 5 without explicitly specifying the type for each property. Am I missing something?
Here's an excerpt from the codebase with a few default values:
Svelte 4:
In Svelte 5, two changes are needed, as far as I could find:
What doesn't work:
Is the conclusion that Svelte 5 is just unavoidably more verbose in this situation?
All reactions