类似于React,我们希望可以为 Props 实现泛型

type Props<T> = {
  items: T[];
  onSelect: (item: T) => void;
};
export const AutoComplete = <T,>(props: Props<T>) => {
  return null;
};

但是在 Svelte 中,直接使用 泛型会报错

<script lang="ts">
  type Props<T> = {
    items: T[];
    onSelect: (item: T) => void;
  };
 
  let { items, onSelect }: Props<T> = $props();
  //         Error here _________^
</script>

因为在 React 中, 组件是函数,当调用时 TypeScript 会自动推断其泛型类型的值。但是 Svelte 并不是函数,而是一段转有的代码,被写入一个 .svelte 文件中,Svelte 编译器将编译其为其他代码。但它并不是一个函数,因此无法直接使用泛型

Svelte 官方提供了 generice 的定义,使得我们可以在组件顶部 script 标签中使用 generice 为组件本身定义泛型

<script lang="ts" generics="T">
  type Props<T> = {
    items: T[];
    onSelect: (item: T) => void;
  };
 
  let { items, onSelect }: Props<T> = $props();
</script>

甚至还可以直接在泛型上定义约束

<script lang="ts" generics="T extends { name: string }">
  type Props<T> = {
    items: T[];
    onSelect: (item: T) => void;
  };
 
  let { items, onSelect }: Props<T> = $props();
</script>