Here is a cool thing we can do in Svelte 5 with Runes. Let's say we make a little utility type like this:
type Holocene<T> = T extends { extends: keyof SvelteHTMLElements }
? Omit<Partial<SvelteHTMLElements[T['extends']]>, keyof T> & Omit<T, 'extends'>
: T;
Now, we can pass an extends
key to the type we give to the props of a component and it will automatically inherit whatever HTML element we choose.
<script lang="ts">
let { label, id, ...props } = $props<Holocene<{ label: string; extends: 'button' }>>();
</script>
<button {id} {...props}>{label}</button>
Since the utility type is clever about omiting properties, you don't have to worry about dumb collisions (e.g. ClassList
is really just a string in practice, but TypeScript doesn't believe that).