Clifton Labrum
Clifton Labrum

Reputation: 14148

Type for Components Passed as Props in Svelte 5

Let's say I have a parent component called 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>

Which I use elsewhere like this:

<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

I'm getting a linter error on the master and detail attributes:

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)

Are components sent as props not of type Snippet? What am I doing wrong?

Upvotes: 2

Views: 926

Answers (1)

Jorge Linares
Jorge Linares

Reputation: 548

The type for components should be Component in Svelte 5, and you just pass it down with a capital first letter so you can directly render it on your SplitView:

//SplitView.svelte
<script lang="ts">
  import type { Component } from 'svelte'

    type Props = {
    Master: Component
    Detail: Component
  }
  
  let { Master, Detail }= $props()
</script>

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

and use like this:

<script lang="ts">
  import SplitView from './SplitView.svelte'
  import MyMaster from './PricingMaster.svelte'
  import Detail from './PricingDetail.svelte'

  // Name your components, Master and Detail to simplify the Props
</script>
  <!-- or use Master={MasterName} Detail={DetailName} 
  to pass components with different component names -->
<SplitView Master={MyMaster} {Detail} />

Upvotes: 6

Related Questions