TypeScript
Vous pouvez utiliser TypeScript dans vos composants Svelte. Les extensions d’IDE comme l’extension
VS Code de Svelte vous
permettent de visualiser les erreurs directement dans votre éditeur, et
svelte-check fait la même chose en ligne de
commande, ce que vous pouvez utiliser dans votre CI.
<script lang="ts">
Pour utiliser TypeScript dans vos composants Svelte, ajoutez lang="ts" à vos balises script :
<script lang="ts">
let name: string = 'les gens';
function greet(name: string) {
alert(`Coucou ${name} !`);
}
</script>
<button onclick={(e: Event) => greet(e.target.innerText)}>
{name as string}
</button>Faire cela vous permet d’utiliser les fonctionnalités de type de TypeScript, c’est-à-dire toutes les fonctionnalités qui disparaissent lorsque vous transpilez vers JavaScript, comme les annotations de type ou les déclarations d’interface. Les fonctionnalités qui demandent au compilateur TypeScript de générer du code ne sont pas supportées. Ceci inclut :
- l’utilisation d’enums
- l’utilisation des modificateurs
private,protectedoupublicdans les fonctions de constructeur couplée à l’initialisation de propriétés. - l’utilisation de fonctionnalités qui ne sont pas encore intégrées au standard ECMASCript (c-à-d qui ne sont pas en stage 4 du processus TC39), et donc pas encore implémentées dans Acorn, le parser que nous utilisons pour interpréter JavaScript.
Si vous souhaitez utiliser une de ces fonctionnalités, vous aurez besoin de mettre en place un
préprocesseur de script.
Mise en place de préprocesseurs
Pour utiliser les fonctionnalités TypeScript non restreintes au type au sein de vos composants, vous aurez besoin d’ajouter un préprocesseur qui va transformer TypeScript en JavaScript.
Using Vite
If you’re using SvelteKit, or Vite without SvelteKit, you can use vitePreprocess from @sveltejs/vite-plugin-svelte in your config file:
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
// Notez le `{ script: true }` additionnel
preprocess: vitePreprocess({ script: true })
};
export default config;Using other build tools
Si vous utilisez plutôt des outils comme Rollup (via
rollup-plugin-svelte) ou Webpack (via
svelte-loader), installez typescript et
svelte-preprocess et ajoutez le préprocesseur à la configuration de plugin. Consultez les fichiers
READMEs des plugins concernés pour plus d’infos.
Si vous commencez un nouveau projet, nous recommandons plutôt d’utiliser SvelteKit ou Vite.
Paramètres de tsconfig.json
Lorsque vous utilisez TypeScript, assurez-vous que votre fichier tsconfig.json soit correctement
défini.
- Utilisez une
targetqui soit au moinsES2015, ou bien unetargetd’au moinsES2015afin que les classes ne soient pas compilées en tant que fonctions - Mettez
verbatimModuleSyntaxàtruepour conserver les imports tels quels - Mettez
isolatedModulesàtruepour que chaque fichier soit considéré en isolation. TypeScript a quelques fonctionnalités qui nécessitent une analyse croisée de fichiers ainsi qu’une compilation, ce que le compilateur de Svelte et des outils comme Vite ne font pas.
Typer les $props
Vous pouvez typer les $props comme un objet normal qui possèderait certaines propriétés.
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
propRequise: number;
propOptionnelle?: boolean;
snippetAvecUnArgumentString: Snippet<[string]>;
gestionnaireEvenement: (arg: string) => void;
[key: string]: unknown;
}
let {
requiredProperty,
optionalProperty,
snippetWithStringArgument,
eventHandler,
...everythingElse
}: Props = $props();
</script>
<button onclick={() => eventHandler('bouton cliqué')}>
{@render snippetWithStringArgument('coucou')}
</button>$props génériques
Les composants peuvent déclarer des relations génériques entre leurs propriétés. Vous pouvez avoir
par exemple un composant de liste qui reçoit en props une liste d’éléments ainsi qu’un callback
ayant pour argument un élément de la liste. Pour déclarer que la propriété items et le callback
select traitent de données du même type, ajoutez l’attribut generics à la balise script :
<script lang="ts" generics="Item extends { text: string }">
interface Props {
items: Item[];
select(item: Item): void;
}
let { items, select }: Props = $props();
</script>
{#each items as item}
<button onclick={() => select(item)}>
{item.text}
</button>
{/each}Le contenu de generics est ce que vous mettriez entre les chevrons <...> d’une fonction
générique. Autrement dit, vous pouvez utiliser plusieurs génériques, extends, ainsi que des types
par défaut.
Typer des composants haut-niveau
Si vous construisez un composant qui englobe un élément natif, vous pourriez vouloir exposer tous
les attributs de l’élément sous-jacent à l’utilisateur. Dans ce cas, utilisez (ou héritez) l’une des
interfaces fournies par svelte/elements. Voici un exemple pour un composant Button :
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
let { children, ...rest }: HTMLButtonAttributes = $props();
</script>
<button {...rest}>
{@render children?.()}
</button>Tous les éléments n’ont pas nécessairement de définition de type dédiée. Pour ceux qui n’en ont pas,
utilisez SvelteHTMLElements :
<script lang="ts">
import type { SvelteHTMLElements } from 'svelte/elements';
let { children, ...rest }: SvelteHTMLElements['div'] = $props();
</script>
<div {...rest}>
{@render children?.()}
</div>Typer $state
Vous pouvez typer $state comme toute autre variable.
let count: number = $state(0);Si vous ne fournissez pas de valeur initiale à $state, son type sera en partie undefined.
// Error: Type 'number | undefined' is not assignable to type 'number'
let count: number = $state();Vous pouvez fournir le type directement en tant que paramètre générique pour gérer ce cas de manière
plus sécurisée. TypeScript va inférer que la variable peut être number | undefined.
let count = $state<number>();Si vous savez que la variable sera définie avant que vous vous en serviez, castez cette variable
avec as. Ceci est particulièrement utile lorsque vous utilisez des classes :
class Counter {
count = $state() as number;
constructor(initial: number) {
this.count = initial;
}
}Le type Component
Les composants Svelte sont de type Component. Vous pouvez vous en servir, ainsi que les types
associés, pour exprimer toute une variété de contraintes.
Cela sert notamment avec les composant dynamiques pour restreindre quels sont les composants qui peuvent leur être fournis :
<script lang="ts">
import type { Component } from 'svelte';
interface Props {
// seuls les composants qui ont au plus la propriété "prop"
// peuvent être fournis
ComposantDynamique: Component<{ prop: string }>;
}
let { ComposantDynamique }: Props = $props();
</script>
<ComposantDynamique prop="foo" />Legacy mode
En Svelte 4, les composants étaient de type
SvelteComponent
Pour extraire le type des propriétés d’un composant, utilisez ComponentProps.
import type { Component, ComponentProps } from 'svelte';
import MonComposant from './MonComposant.svelte';
function withProps<TComponent extends Component<any>>(
component: TComponent,
props: ComponentProps<TComponent>
) {}
// Affiche une erreur si le deuxième argument n'a pas les props attendues
// par le composant en premier argument
withProps(MonComposant, { foo: 'bar' });Pour déclarer qu’une variable attend le constructeur ou une instance d’un composant :
<script lang="ts">
import MyComponent from './MyComponent.svelte';
let componentConstructor: typeof MyComponent = MyComponent;
let componentInstance: MyComponent;
</script>
<MyComponent bind:this={componentInstance} />Améliorer les types natifs du DOM
Svelte fait son maximum pour fournir les types de tous les éléments du DOM existants. Il se peut que parfois, vous vouliez utiliser des attributs expérimentaux ou des évènements personnalisés venant d’une action. Dans ces cas-là, TypeScript va lever une erreur, vous disant qu’il ne connait pas ces types. S’il s’agit d’attributs ou d’évènements standards non-expérimentaux, cela peut simplement être un oubli dans nos définitions de types HTML. Dans ce cas, vous pouvez ouvrir une issue et/ou une PR pour corriger le problème.
S’il s’agit d’un évènement/attribut expérimental, vous pouvez améliorer le typage en augmentant le
module svelte/elements de cette manière :
import { HTMLButtonAttributes } from 'svelte/elements';
declare module 'svelte/elements' {
// ajoute un nouvel élément
export interface SvelteHTMLElements {
'bouton-perso': HTMLButtonAttributes;
}
// ajout un nouvel attribut global qui est disponible sur tous les éléments HTML
export interface HTMLAttributes<T> {
globalattribute?: string;
}
// ajoute un nouvel attribut pour les éléments bouton
export interface HTMLButtonAttributes {
attributtresexperimental?: string;
}
}
export {}; // assure que ceci n'est pas un module ambiant, sans quoi les types seraient écrasésAssurez-vous ensuite que le fichier .d.ts est référencé dans votre fichier tsconfig.json. S’il
contient quelque chose comme "include": ["src/**/*"] et que votre fichier .d.ts se trouve dans
src, cela devrait fonctionner. Vous aurez peut-être besoin de recharger pour que les changements
aient de l’effet.
Modifier cette page sur Github llms.txt