Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

How to use $$Generic with an array prop in svelte component?

$
0
0

I need to inject nested components through a property while keeping a strong typing.Using slots doesn't work for me because they don't allow me to switch easily between the components to be used. This would be possible if the slot names could be dynamic but unfortunately this is not the case (see this issue).

Using $$Generic in the following example, all element types are based on the first one.

Dynamic.svelte

<script lang="ts">    import type { ComponentProps, ComponentType, SvelteComponentTyped } from 'svelte'    type Component = $$Generic<SvelteComponentTyped>    type ComponentAndProps = {        component: ComponentType<Component>        props: ComponentProps<Component>    }    export let array: ComponentAndProps[] = []</script>{#each array as item}<svelte:component this={item.component} {...item.props} />{/each}

Test.svelte

<script lang="ts">    import Dynamic from './Dynamic.svelte'    import A from './A.svelte' // export let a: string    import B from './B.svelte' // export let b: string</script><Dynamic    array={[        {            component: A,            props: { a: 'work fine' },        },        {            // <-- Type 'typeof B__SvelteComponent_' is not assignable to type 'ComponentType<A__SvelteComponent_>'            component: B,            props: { b: '' },        },    {      component: A,      props: { a: 'work fine too'}    }    ]}/>

I found no way to deduce the type of props for each item separately.

Do you have an idea or a solution?

Edit

I ended up using a function to link my component and its properties.

utils.ts

import type { ComponentProps, ComponentType } from 'svelte'export type ComponentAndProps = {    component: ComponentType    props: ComponentProps<InstanceType<ComponentType>>}export function component<Component extends ComponentType>(    component: Component,    props: ComponentProps<InstanceType<Component>>): ComponentAndProps {    return { component, props }}

Dynamic.svelte

<script lang="ts">  import type { ComponentAndProps } from '$lib/utils'  export let array: ComponentAndProps[] = []</script>{#each array as item}<svelte:component this={item.component} {...item.props} />{/each}

Test.svelte

<script lang="ts">    import { component } from './utils'    import Dynamic from './Dynamic.svelte'    import A from './A.svelte' // export let a: string    import B from './B.svelte' // export let b: string</script><Dynamic    array={[        component(A, {a: 'hey'}),        component(B, {b: 'mom'})    ]}/>

This also works with a generic type. For render a table row, for example:

<script lang="ts">    import type { ComponentAndProps } from './utils'    type Item = $$Generic    export let item: Item    export let fields: ((item: Item) => ComponentAndProps)[]</script>{#each fields as field}    {@const { component, props } = field(item)}<svelte:component this={component} {...props} />{/each}

Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>