Skip to content

Improve typing on children property in HTMLAttributes #13598

@kwangure

Description

@kwangure

Describe the bug

The elements in 'svelte/elements' extend the following type:

export interface DOMAttributes<T extends EventTarget> {
	// Implicit children prop every element has
	// Add this here so that libraries doing `let { ...props }: HTMLButtonAttributes = $props()` don't need a separate interface
	children?: import('svelte').Snippet;
}

The children property on the interface is intended to allow uses case like these:

<script lang='ts'>
	import type { HTMLButtonAttributes } from 'svelte/elements';
	const { children, ...restProps }: HTMLButtonAttributes = $props();
</script>

<button {...restProps}>{@render children?.()}</button>

But inadvertently now prevents uses like these:

<script lang='ts'>
	import type { HTMLButtonAttributes } from 'svelte/elements';
	import type { Snippet } from 'svelte';

	interface Props /* <-- error */ extends HTMLButtonAttributes  {
		children: Snippet<[string]>
	}
	const { children, ...restProps }: Props = $props();
</script>

<button {...restProps}>{@render children?.('foo')}</button>

With the error being:

Interface 'Props' incorrectly extends interface 'HTMLButtonAttributes'.
  Types of property 'children' are incompatible.
    Type 'Snippet<[string]>' is not assignable to type 'Snippet<[]>'.
      Target signature provides too few arguments. Expected 1 or more, but got 0.

It would be nice if this supported both patterns of usage.

That said, it is possible to use in its current state, though not great.

interface Props extends Omit<HTMLButtonAttributes, 'children'>  {
	children: Snippet<[string]>
}

Reproduction

N/A

Logs

No response

System Info

svelte: ^5.0.0-next.264 => 5.0.0-next.264

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions