sveltejs / sveltejs/language-tools

Improve DX for extending HTML elements with Typescript props

Open
#2,016 11 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature request
Dominant language
TypeScript
Stars
1.4k
Forks
252
Avg merge
8d 13h
Merged PRs (30d)
2

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the Svelte compiler's handling of $$Props and exported component props, using the HTMLButtonAttributes example as the starting case. Define a supported way to inherit base HTML props without duplicating the variant type, then verify the resulting TypeScript behavior for custom components.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
developer-experience, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.