简体   繁体   中英

How to use svelte:component with TypeScript?

I would like to use a dynamic component to select a view depending on the value of an enum:

<svelte:component
  this={components[enumValue]}
  {...props}
/>

But I don't get a compile error if I don't pass all the necessary parameters:

<svelte:component
  this={components[enumValue]}
/>

How to correctly specify the typing of dynamic components?


UPD: map example with React

const props: Props = {...}
const components: Record<EnumType, React.FC<Props>> = {
  [EnumType.variant_1]: Component1,
  [EnumType.variant_2]: Component2,
}

You can apply a little indirection using a generic wrapper component. Eg

<!-- renderer.svelte -->
<script lang="ts">
    import type { SvelteComponentTyped } from 'svelte/internal';

    type C = $$Generic<typeof SvelteComponentTyped<any, any, any>>;

    export let component: C;
    export let props: C extends typeof SvelteComponentTyped<infer P> ? P : never;
</script>

<svelte:component this={component} {...props} />

Usage example:

<!-- adder.svelte -->
<script lang="ts">
    export let a: number;
    export let b: number;
</script>

{a} + {b} = {a + b}
<script lang="ts">
    import Renderer from './renderer.svelte';
    import Adder from './adder.svelte';
</script>

<Renderer component={Adder} />
<!-- Error on "Renderer" because props are missing -->

<Renderer component={Adder} props={{ a: 12 }} />
<!-- Error on "props": Property 'b' is missing in type '{ a: number; }'
                       but required in type '{ a: number; b: number; }' -->

This may require very recent versions of svelte / svelte-preprocess to work correctly with the generics. You could also drop the generics and type the renderer's properties more loosely. Having props as an export of another component at the very least ensures the props missing error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM