Skip to content

Improve DX for extending HTML elements with Typescript props #2016

Open
@dan-cooke

Description

@dan-cooke

Describe the problem

I am finding it quite awful when extending base HTML elements.

For example I want to create a custom <Button /> that has a single new prop called variant

Sofar I can see the only method for doing this is as follows:

<script lang="ts">
	// Import from elements package - nice so far
	import type { HTMLButtonAttributes } from 'svelte/elements';
    
    // Ok have to export this prop for consumers to use
   // Note the type annotation here too
	export let variant: 'primary' | 'secondary' = 'primary'
    
    // Okay... i have to extend this interface now to actually extend the buton props
   // but typescript complains so I have to redeclare the variant type here too
   // with the exact same type definition?
   // this just doubles the amount of code you have to write for thsi kind of thing

	interface $$Props extends Partial<HTMLButtonAttributes> {
		variant: 'primary' | 'secondary';
	}
</script >

I have only ever seen this example given when this question has come up on Discord, and on StackOverflow - I feel like there has to be a better way

Describe the proposed solution

If possible the Svelte compiler could combine the defined $$Props definition with everything that is exported from the component - that would completely solve this issue

To extend it would be amazing if you could just do something like

export let $$BaseProps: HTMLButtonAttributes;

Then all Svelte has to do is say

interface $$Props extends typeof $$BaseProps (HTMLButtonAttributes), OtherPropsExported {}

Alternatives considered

  • export let variant: $$Props['variant'] - prevents having to type Type defintiions twice, but still not 100% amazing solution, as you still have to type that out for every prop you are adding

Importance

nice to have

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions