-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Open
Labels
Milestone
Description
Describe the problem
This is how you currently render the children within a component:
<!--my-component.svelte-->
<script lang="ts">
import type { Snippet } from "svelte";
type Props = {
children?: Snippet
}
let { children }: Props = $props()
</script>
<div>
My children are:
</div>
{@render children?.()}
<!--+page.svelte-->
<MyComponent>
<p> Peter </p>
</MyComponent>
Although, using typescript, there is no way to define what the content of children
within <MyComponent>
should be.
Describe the proposed solution
I would like to define the type of children in the component, so that typescript only allows some specific elements or components to be children:
<!-- This should trigger an error in typescript. -->
<MyComponent>
<p> Peter </p>
</MyComponent>
<!-- This should also trigger an error in typescript. -->
<MyComponent>
<NotTheTypedComponentInMyComponent/>
</MyComponent>
<!-- This should be OK. -->
<MyComponent>
<TheCorrectComponent/>
</MyComponent>
This should be done somehow similar to this:
<!--my-component.svelte-->
<script lang="ts">
import MyComponent from "$lib/my-component.svelte"
type Props = {
children?: MyComponent // This does not work, but something similar to this.
}
let { children }: Props = $props()
...
Importance
would make my life easier
lassebomh and osamakawish
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
7nik commentedon May 29, 2025
What is the point of limiting
children
type? Why your component cannot accept<p> Peter </p>
or<NotTheTypedComponentInMyComponent/>
?MotionlessTrain commentedon May 29, 2025
If it can only accept a couple of components, it would make more sense to give the component as property instead, and have that in the correct place in the template instead. Then it can be typed much more easily
paoloricciuti commentedon May 29, 2025
Sometimes it could be useful, if you build something like this for example you might want the children to only be
TabItems
because every other children will not work or even disrupt your component.Someone might argue that this is not the right way of doing it but i think it could be useful sometimes. The real problem is that snippets don't "return" anything so it could be difficult to type check that.
Regardless this is more an issue for
language-tools
as svelte can't do much here.7nik commentedon May 29, 2025
Can it even be type-checked?
Tab
expects exactlyTabItem
s in children, but for TS, there is no difference between<TabItem name="tab 1">
and<RandomComponent name="John">
with compatible set of props.MotionlessTrain commentedon May 29, 2025
And what if ’s template actually is nothing else but a bunch of s?
paoloricciuti commentedon May 29, 2025
Yeah it's definitely not straight forward, probably not even doable.
OTheNonE commentedon May 30, 2025
I can let you in on my use-case:
I am creating a small svelte-wrapper for my implementation of OpenLayers in my app. This is a tiny somewhat simplified part of the code:
In the
map.svelte
andtile-layer.svelte
component, all components are allowed aschildren
, eventhough it does not make sense for some components to be child of map. E.g. the classOSM()
must be a child ofTileLayer()
, andTileLayer()
must be child ofMap()
, through the method of.addLayer()
andsetSource()
(enforced by Typescript). I was hoping that i could enforce the same restrictions within components childrens.7nik commentedon May 30, 2025
For now, the best you can do is throwing an error
<X> must be inside <Y>
when a component fails to get the right context.