TypeScript интеграция

SvelteKit изначально поддерживает TypeScript, что позволяет создавать строго типизированные приложения. Для включения TypeScript достаточно создать проект с флагом --typescript при инициализации:

npm create svelte@latest my-app -- --template sveltekit-ts

После создания проекта в корне появятся файлы tsconfig.json и svelte.config.ts. В tsconfig.json задаются глобальные настройки компилятора TypeScript, включая строгую типизацию:

{
  "extends": "./.svelte-kit/tsconfig.json",
  "compilerOptions": {
    "strict": true,
    "baseUrl": ".",
    "paths": {
      "$lib/*": ["src/lib/*"]
    }
  }
}

Ключевой момент — "strict": true, который включает набор правил строгой типизации, предотвращая ошибки на этапе компиляции.


Типизация компонентов Svelte

В SvelteKit каждый компонент .svelte можно типизировать через TypeScript с использованием интерфейсов для пропсов:

<script lang="ts">
  export let title: string;
  export let count: number;
</script>

<h1>{title}</h1>
<p>Количество: {count}</p>

Можно также использовать интерфейсы для группировки пропсов:

<script lang="ts">
  interface Props {
    title: string;
    count: number;
    active?: boolean;
  }

  export let props: Props;
</script>

<h1>{props.title}</h1>
<p>{props.count}</p>
{#if props.active}Активен{/if}

Опциональные поля (active?: boolean) позволяют задавать значения, которые могут отсутствовать без нарушения типизации.


Типизация событий и bind

SvelteKit поддерживает строго типизированные события компонентов. Пример передачи событий с указанием типов:

<script lang="ts">
  import { createEventDispatcher } from 'svelte';
  
  const dispatch = createEventDispatcher<{ submit: { value: string } }>();

  function handleSubmit() {
    dispatch('submit', { value: 'Пример' });
  }
</script>

<button on:click={handleSubmit}>Отправить</button>

В родительском компоненте можно получить автодополнение при подписке на события:

<Child on:submit={(e) => console.log(e.detail.value)} />

e.detail строго типизирован, что исключает ошибки при доступе к свойствам.


Типизация сторов

SvelteKit UI библиотеки часто используют Svelte stores. Их также можно строго типизировать:

import { writable, type Writable } from 'svelte/store';

interface User {
  id: number;
  name: string;
  email: string;
}

export const user: Writable<User | null> = writable(null);

Подписка на store обеспечивает автодополнение и проверку типов:

$user; // Если user = null, TypeScript предупредит о потенциальной ошибке

Для derived store также возможно указание типа:

import { derived } from 'svelte/store';

export const userName = derived(user, ($user) => $user?.name ?? 'Гость');

Типизация маршрутов и load-функций

SvelteKit использует load функции для получения данных на сервере или клиенте. Они полностью поддерживают TypeScript:

import type { PageLoad } from './$types';

export const load: PageLoad = async ({ fetch }) => {
  const res = await fetch('/api/data');
  const data: { id: number; title: string }[] = await res.json();
  return { data };
};

Использование интерфейсов обеспечивает проверку структуры данных на этапе компиляции, предотвращая ошибки при рендеринге.


Интеграция с UI библиотеками

Многие UI библиотеки для Svelte (например, Svelte Material UI, Flowbite-Svelte) предоставляют собственные типы:

import Button from 'svelte-material-ui/button';
import type { ButtonProps } from 'svelte-material-ui/button';

let props: ButtonProps = {
  variant: 'raised',
  color: 'primary'
};

Типизация пропсов позволяет использовать автодополнение и предотвращает передачу некорректных значений.


Модули и декларации типов

Для библиотек без встроенной поддержки TypeScript создаются декларации типов:

// src/lib/types/ui-lib.d.ts
declare module 'my-ui-lib' {
  import type { SvelteComponent } from 'svelte';
  export class MyComponent extends SvelteComponent {
    $$prop_def: {
      label: string;
      active?: boolean;
    };
  }
}

После этого TypeScript будет проверять корректность использования компонента в проекте.


Использование svelte-check и ESLint

Для поддержания строгой типизации важно использовать инструменты проверки:

npm install -D svelte-check eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

Конфигурация ESLint:

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": ["plugin:@typescript-eslint/recommended"],
  "overrides": [
    {
      "files": ["*.svelte"],
      "processor": "svelte3/svelte3"
    }
  ]
}

svelte-check позволяет выявлять ошибки в .svelte файлах до запуска приложения, а ESLint следит за стилем кода и соблюдением типизации.


Типизация контекста и слотов

Контекст компонента через setContext и getContext также поддерживает типы:

import { setContext, getContext } from 'svelte';

interface ThemeContext {
  color: string;
  darkMode: boolean;
}

setContext<ThemeContext>('theme', { color: 'blue', darkMode: true });

const theme = getContext<ThemeContext>('theme');
console.log(theme.color);

Слоты можно типизировать через интерфейсы пропсов:

<script lang="ts">
  export interface SlotProps {
    message: string;
  }
</script>

<slot {message}></slot>

TypeScript в SvelteKit обеспечивает полную интеграцию типизации на уровне компонентов, сторов, маршрутов, событий и сторонних UI библиотек, что делает разработку безопасной и предсказуемой. Строгие интерфейсы и декларации позволяют минимизировать ошибки на этапе компиляции и получить автодополнение в редакторах, повышая производительность при работе с крупными проектами.