You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte 5中作为Props传递的组件类型定义问题

问题:传递组件给Snippet类型Props时出现TypeScript错误

我有一个名为SplitView.svelte的父组件,代码如下:

<script lang="ts">
  import type { Snippet } from 'svelte'
  
  type Props = {
    master: Snippet
    detail: Snippet
  }
  let { master, detail }: Props = $props()
</script>

<div class="split">
  <div id="master">
    {@render master()}
  </div>
  <div id="detail">
    {@render detail()}
  </div>
</div>

我在其他地方这样使用该组件:

<script lang="ts">
  import SplitView from '$lib/components/shared/SplitView.svelte'
  import Master from './master/PricingMaster.svelte'
  import Detail from './detail/PricingDetail.svelte'
</script>

<SplitView master={Master} detail={Detail} /> <!-- ESLint error -->

此时在master和detail属性上收到ESLint错误提示:

Type '__sveltets_2_IsomorphicComponent<Record<string, never>, 
{ [evt: string]: CustomEvent<any>; }, {}, {}, string>' is not assignable to type 'Snippet<[]>'.

Target signature provides too few arguments. Expected 2 or more, but got 0.ts(2322)

作为Props传递的组件是否不属于Snippet类型?我哪里操作错误了?


解决方法

组件和Snippet是完全不同的类型,你的核心错误是把组件(ComponentType类型)当成了Snippet类型传递。以下是两种修正方案:

方案一:修改SplitView接收组件类型Props

将SplitView的Props类型从Snippet改为ComponentType,并使用组件标签的方式渲染:

<script lang="ts">
  import type { ComponentType } from 'svelte'
  
  type Props = {
    master: ComponentType
    detail: ComponentType
  }
  // 遵循Svelte组件名大写约定,重命名变量
  let { master: Master, detail: Detail }: Props = $props()
</script>

<div class="split">
  <div id="master">
    <Master />
  </div>
  <div id="detail">
    <Detail />
  </div>
</div>

修改后,原有的组件调用方式<SplitView master={Master} detail={Detail} />就能正常工作,不会再触发类型错误。

方案二:保持SplitView使用Snippet,修改调用方式

如果需要继续使用Snippet类型,要在调用时传递代码片段而非组件本身,使用Svelte的{#snippet}语法:

<script lang="ts">
  import SplitView from '$lib/components/shared/SplitView.svelte'
  import Master from './master/PricingMaster.svelte'
  import Detail from './detail/PricingDetail.svelte'
</script>

<SplitView>
  {#snippet master()}
    <Master />
  {/snippet}
  {#snippet detail()}
    <Detail />
  {/snippet}
</SplitView>

这种写法是Svelte中传递代码片段的标准方式,父组件的{@render master()}会正确渲染对应的内容。


类型区别说明

  • Snippet:是一段可渲染的代码片段,通过{#snippet}定义,本质是一个渲染函数,调用时执行渲染逻辑。
  • ComponentType:导入的组件属于此类型,是组件的构造函数,必须通过<Component />标签或相关API创建实例并渲染。

内容的提问来源于stack exchange,提问作者Clifton Labrum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:44:50