Kevin Renskers
Kevin Renskers

Reputation: 5960

Svelte components with generics

I want to use a generic type in a Svelte(Kit) component's props, and I found out there is this type T = $$Generic thing:

<script lang="ts">
  import type { Writable } from "svelte/store";
  type T = $$Generic;
  export let store: Writable<T[]>;
</script>

While that is great, I do need slightly more information than that: I require that the T has a property id. Normally I'd do something like this:

export type WithId = { id: number };
function foo<T extends WithId>(property: T) { ... }

How can I do something similar for Svelte component props?

Upvotes: 14

Views: 15772

Answers (2)

Tobsic
Tobsic

Reputation: 51

The answer by @brunnerh is already very good. But in order to have no eslint errors, the generic type T needs to be defined in typescript and not only the generics attribute of the <script>. This will hopefully change in the future.

<script lang="ts" context="module">
  type T = { id: number };
</script>

<script lang="ts" generics="T extends { id: number }">
  import type { Writable } from "svelte/store";
  export let store: Writable<T[]>;
</script>

Upvotes: 5

brunnerh
brunnerh

Reputation: 185445

Edit: The design was changed, generics should now be defined as an attribute which uses the regular extends keyword:

<script lang="ts" generics="T extends { id: number }">

RFC


You can specify the type it extends like this:

type T = $$Generic<{ id: number }>;

You can also use type or interface names, though if you define them within a component, you might have to place them in the module script, i.e. something like this:

<script lang="ts" context="module">
    interface WithId { id: number }
</script>
<script lang="ts">
    export let store: Writable<T[]>;

    type T = $$Generic<WithId>;
</script>

Upvotes: 31

Related Questions