Skip to content

Svelte 5: Composable components, {@render ...} throws type errors whether it is a Component or Snippet type. #15128

Closed as duplicate of#9774
@robertkibet

Description

@robertkibet

Describe the bug

Building Composable components is problematic with TypeScript. Slots used to work well, the new {@render ...} method seems to cause some Type errors with Snippets/Component types 🤔

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

 type ButtonProps = {
    text?: string;
    icon?: Component;
  };

  let {icon, text}:ButtonProps = $props()
</script>

<div class="content">
  {#if icon}
    {@render icon()}
  {/if}
  {text}
</div>

Above code snippet throws a type error:

/home/projects/svelte-render-component-type/src/lib/Button.svelte:14:14
Error: Argument of type '{ $on?(type: string, callback: (e: any) => void): () => void; $set?(props: Partial<{}>): void; }' is not assignable to parameter of type '{ '{@render ...} must be called with a Snippet': "import type { Snippet } from 'svelte'"; } & unique symbol'.
Property ''{@render ...} must be called with a Snippet'' is missing in type '{ $on?(type: string, callback: (e: any) => void): () => void; $set?(props: Partial<{}>): void; }' but required in type '{ '{@render ...} must be called with a Snippet': "import type { Snippet } from 'svelte'"; }'. (ts)

And if I update the type to use Snippets, it still throws an error, the error is now thrown in the parent component

// Button.svelte file
<script lang="ts">
  import type { Snippet } from 'svelte';

 type ButtonProps = {
    text?: string;
    icon?: Snippet;
  };

  let {icon, text}:ButtonProps = $props()
</script>

<div class="content">
  {#if icon}
    {@render icon()}
  {/if}
  {text}
</div>
// App.svelte file throws a type error
<Button text="I can accept props" icon={CustomIcon} />

The type error thrown is this:

/home/projects/svelte-render-component-type/src/App.svelte:11:39
Error: Type '__sveltets_2_IsomorphicComponent<{ [x: string]: never; }, { [evt: string]: CustomEvent; }, {}, {}, string>' is not assignable to type 'Snippet<[]>'.
Target signature provides too few arguments. Expected 2 or more, but got 0. (ts)

Previously in Svelte v4 I would just use <svelte:component this={icon} /> and it would work well.
Ref: https://svelte.dev/docs/svelte/v5-migration-guide#svelte:component-is-no-longer-necessary

Reproduction

Please fork and test this stackblitz project: https://stackblitz.com/edit/svelte-render-component-type?file=src%2Flib%2FButton.svelte

Steps:

  • Access the terminal
  • run npm check
  • you should see the type errors

Logs

System Info

~/projects/svelte-render-component-type 24s
❯ npx envinfo --system --npmPackages svelte,rollup,webpack --binaries --browsers
Need to install the following packages:
envinfo@7.14.0
Ok to proceed? (y) y

  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    svelte: ^5.19.3 => 5.19.3

Severity

annoyance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions