-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Describe the problem
The module "svelte/elements" provides the definitions of HTML attributes that can be used to declare props to spread in a component that "wrap" a HTML element.
For example for a component Button, using directly the type HTMLButtonAttributes
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
let { children, ...rest } : HTMLButtonAttributes = $props();
</script>
<button {...rest}>
{@render children?.()}
</button>Or via the equivalent using SvelteHTMLElements
<script lang="ts">
import type { SvelteHTMLElements } from 'svelte/elements';
let { children, ...rest } : SvelteHTMLElements['button'] = $props();
</script>
<button {...rest}>
{@render children?.()}
</button>But there are 2 flaws :
- This include the definition of
bind:andon:directives, which are therefore proposed by autocompletion - The children is defined with zero parameter, and this cannot be changed easily.
In order to remove the bind:/on: directives, II need to write something like that :
let { children, ...rest } : Omit<HTMLButtonAttributes, `bind:${string}` | `on:${string}`> = $props();And if I need to specify a parameter for the children snippet, I have to write :
let { children, ...rest } : Omit<HTMLButtonAttributes, `bind:${string}` | `on:${string}` | 'children'>
& { children?: Snippet<[number]> } = $props();Describe the proposed solution
It would be nice if Svelte 5 had an official type to handle this in "svelte/elements".
Something like this might work :
export type SvelteHTMLProps<TagName extends string, Parameters extends unknown[] = []> = {
children?: import('svelte').Snippet<Parameters>;
} & Omit<SvelteHTMLElements[TagName], `bind:${string}` | `on:${string}` | `children`>;So we can use SvelteHTMLProps<'button'>in order to define our Button component :
<script lang="ts">
import type { SvelteHTMLProps } from 'svelte/elements';
let { children, ...rest } : SvelteHTMLProps<'button'> = $props();
</script>
<button {...rest}>
{@render children?.()}
</button>Or SvelteHTMLProps<'button', [number]>to define the children parameter type :
<script lang="ts">
import type { SvelteHTMLProps } from 'svelte/elements';
let { children, onclick, ...rest } : SvelteHTMLProps<'button', [number]> = $props();
let count = $state(0);
function countClick(evt) {
count++;
onclick?.(evt);
}
</script>
<button onclick={countClick} {...rest}>
{@render children?.(count)}
</button> Importance
nice to have