-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Restricting children
to Specific Components in Svelte with TypeScript
#16025
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What is the point of limiting |
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 |
Sometimes it could be useful, if you build something like this for example you might want the children to only be 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 |
Can it even be type-checked? |
And what if ’s template actually is nothing else but a bunch of s? |
Yeah it's definitely not straight forward, probably not even doable. |
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: <!--+page.svelte-->
<script lang="ts">
import { Map, OpenStreetMap } from "$lib/ol/components"
</script>
<Map>
<TileLayer>
<OpenStreetMap/>
</TileLayer>
</Map> <!--map.svelte-->
<script lang="ts">
import { setMapContext } from "./ctx";
import type { Snippet } from "svelte";
import Map from "ol/Map.js"
import View from "ol/View";
type Props = {
children?: Snippet
}
const { children }: Props = $props()
let map_element: HTMLDivElement
let map = $state<Map>()
setMapContext(() => map)
const view = new View({ ... })
$effect(() => {
map = new Map({
target: map_element,
view
})
return () => map?.dispose()
})
</script>
<div class="h-full" bind:this={map_element}>
{#if map}
{@render children?.()}
{/if}
</div> <!--tile-layer.svelte-->
<script lang="ts">
import TileLayer from "ol/layer/Tile";
import { OSM } from "ol/source";
import { setTileLayerContext, getMapContext } from "./ctx";
import Layer from "ol/layer/Layer";
const layer = new TileLayer()
setTileLayerContext(() => layer)
const map = getMapContext()
$effect(() => {
map.addLayer(layer)
return () => map.removeLayer(layer)
})
</script> <!--openstreetmap.svelte-->
<script lang="ts">
import TileLayer from "ol/layer/Tile";
import { OSM } from "ol/source";
import { getTileLayerContext } from "./ctx";
const source = new OSM()
const layer = getTileLayerContext()
$effect(() => {
layer.setSource(source)
return () => layer.removeLayer(source)
})
</script> In the |
For now, the best you can do is throwing an error |
Describe the problem
This is how you currently render the children within a component:
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 be done somehow similar to this:
Importance
would make my life easier
The text was updated successfully, but these errors were encountered: