No meu aplicativo Svelte 4, carrego dinamicamente componentes, todos com props diferentes. Reprodução muito simples (também disponível no Svelte Playground ):
// App.svelte
<script lang="ts">
import One from "./One.svelte";
import Two from "./Two.svelte";
import type { ComponentType } from "svelte";
type Item = {
component: ComponentType;
};
const items: Item[] = [
{ component: One, one: "World" },
{ component: Two, two: "Svelte" },
];
</script>
<div class="container py-20 text-white">
{#each items as item}
<div>
<svelte:component this={item.component} {...item} />
</div>
{/each}
</div>
// One.svelte
<script lang="ts">
export let one;
</script>
Hello {one}
// Two.svelte
<script lang="ts">
export let two;
</script>
Goodbye {two}
Isso funciona bem sem nenhum aviso ou erro, sem reclamações até agora. No entanto, quero migrar para o Svelte 5 e agora estou recebendo um monte de erros do TypeScript. Por exemplo, ComponentType
está obsoleto, e coisas assim:
Type '__sveltets_2_IsomorphicComponent<{ one: any; }, { [evt: string]: CustomEvent<any>; }, {}, {}, string>' is not assignable to type 'ComponentType'.
Type '__sveltets_2_IsomorphicComponent<{ one: any; }, { [evt: string]: CustomEvent<any>; }, {}, {}, string>' is not assignable to type 'new (options: ComponentConstructorOptions<Record<string, any>>) => SvelteComponent<Record<string, any>, any, any>'.
Types of parameters 'options' and 'options' are incompatible.
Type 'ComponentConstructorOptions<Record<string, any>>' is not assignable to type 'ComponentConstructorOptions<{ one: any; }>'.
Property 'one' is missing in type 'Record<string, any>' but required in type '{ one: any; }'.
Como posso refatorar meu código para que ele continue funcionando, sem erros de TypeScript e sem ter que tipar fortemente cada componente? No meu aplicativo do mundo real, há muitos componentes envolvidos, cada um com um monte de props diferentes. Não quero ter que criar aliases de tipo para cada um deles.
A simples alteração ComponentType
para Component
elimina o aviso de descontinuação, mas o outro aviso ainda é basicamente o mesmo:
Type '__sveltets_2_IsomorphicComponent<{ one: any; }, { [evt: string]: CustomEvent<any>; }, {}, {}, string>' is not assignable to type 'Component<{}, {}, string>'.
Types of parameters 'props' and 'props' are incompatible.
Type '{}' is not assignable to type '{ one: any; } & { $$events?: { [evt: string]: CustomEvent<any>; } | undefined; $$slots?: {} | undefined; }'.
Property 'one' is missing in type '{}' but required in type '{ one: any; }'.ts(2322)
Mudar ComponentType
para SvelteComponent
também não melhora as coisas. Quando uso o unknown
tipo, recebo este aviso:
Argument of type 'unknown' is not assignable to parameter of type 'ConstructorOfATypedSvelteComponent | Component<any, any, any> | null | undefined'.
Pelo menos é apenas um aviso em vez de vários no array, então é melhor, mas isso não pode ser resolvido de uma maneira melhor (sem digitar cada componente)?
unknown
significa que você tem que afirmar um tipo primeiro para usá-lo de forma significativa. Se você quiser ser menos rigoroso, você deveany
:(Deve haver maneiras de alinhar os adereços com o tipo de componente fornecido usando genéricos, mas isso é um pouco mais complicado.)
No Svelte 5 você também não deve usar
<svelte:component>
, você pode usar o componente diretamente:(Nome em minúsculas só é permitido por meio da
.
notação.)