如何将 svelte:component 与 TypeScript 一起使用?

Vit*_*ali 8 typescript svelte

我想使用动态组件根据枚举的值选择视图:

<svelte:component
  this={components[enumValue]}
  {...props}
/>
Run Code Online (Sandbox Code Playgroud)

但如果我不传递所有必要的参数,我不会收到编译错误:

<svelte:component
  this={components[enumValue]}
/>
Run Code Online (Sandbox Code Playgroud)

如何正确指定动态组件的类型?


UPD:React 的地图示例

const props: Props = {...}
const components: Record<EnumType, React.FC<Props>> = {
  [EnumType.variant_1]: Component1,
  [EnumType.variant_2]: Component2,
}
Run Code Online (Sandbox Code Playgroud)

H.B*_*.B. 12

您可以使用通用包装器组件应用一些间接方法。例如

<!-- renderer.svelte -->
<script lang="ts" generics="C extends ComponentType">
    import type { ComponentType, ComponentProps } from 'svelte';

    export let component: C;
    export let props: ComponentProps<InstanceType<C>>;
</script>

<svelte:component this={component} {...props} />
Run Code Online (Sandbox Code Playgroud)

使用示例:

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

{a} + {b} = {a + b}
Run Code Online (Sandbox Code Playgroud)
<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; }' -->
Run Code Online (Sandbox Code Playgroud)

svelte这可能需要/的最新版本svelte-preprocess才能与泛型正确配合。您还可以删除泛型并更宽松地键入渲染器的属性。作为props另一个组件的导出至少可以确保道具丢失错误。