Svelte コンポーネント内では TypeScript が使用できます。Svelte VSCode extension などの IDE の拡張機能を使用すると、エディター上でエラーをすぐに見つけやすくなります。また、svelte-check
は同じことをコマンドライン上で実行できるため、CI と統合できます。
セットアップpermalink
Svelte コンポーネント内で TypeScript を使用するには、TypeScript を JavaScript に変換するプリプロセッサーを追加する必要があります。
SvelteKit または Vite を使用するpermalink
TypeScript を使い始めるのに最も簡単な方法は、npm create svelte@latest
とタイプして、新しい SvelteKit プロジェクトを scaffold し、プロンプトに従って TypeScript オプションを選択することです。
ts
import {vitePreprocess } from '@sveltejs/kit/vite';constconfig = {preprocess :vitePreprocess ()};export defaultconfig ;
SvelteKit が提供するすべての機能が必要ではない場合は、npm create vite@latest
とタイプして svelte-ts
オプションを選ぶことで、Svelte 向けの Vite プロジェクトを scaffold できます。
ts
import {vitePreprocess } from '@sveltejs/vite-plugin-svelte';constconfig = {preprocess :vitePreprocess ()};export defaultconfig ;
いずれの場合でも、vitePreprocess
を使用した svelte.config.js
が追加されます。Vite/SvelteKit はこの設定ファイルを読み込みます。
その他のビルドツールpermalink
代わりに Rollup や Webpack のようなツールを使用している場合、ツール向けの Svelte プラグインをインストールしてください。Rollup の場合は rollup-plugin-svelte、Webpack の場合はsvelte-loader です。どちらの場合も、typescript
と svelte-preprocess
をインストールして、プリプロセッサーをプラグインの設定に追加する必要があります(より詳しい情報については、それぞれのREADMEを確認してください)。新しいプロジェクトを開始する場合には、rollup や webpack のテンプレートを使ってスクリプトからセットアップを scaffold することもできます。
新しいプロジェクトを開始する場合は、代わりに SvelteKit または Vite を使うことをおすすめします。
<script lang="ts">permalink
Svelte コンポーネント内で TypeScript を使うには、lang="ts"
を script
タグに追加します。
<script lang="ts">
let name: string = 'world';
function greet(name: string) {
alert(`Hello, ${name}!`);
}
</script>
Propspermalink
Props は、export let
文に直接型付けできます。
<script lang="ts">
export let name: string;
</script>
Slotspermalink
Slot と slot prop の型は、渡された slot props の型から推論されます。
<script lang="ts">
export let name: string;
</script>
<slot {name} />
<!-- Later -->
<Comp let:name>
<!-- ^ string として推論される -->
{name}
</Comp>
Eventspermalink
Event は createEventDispatcher
を使って型付けできます。
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
event: null; // payload を受け付けない
click: string; // 必須の string の payload を持つ
type: string | null; // オプションの string payload を持つ
}>();
function handleClick() {
dispatch('event');
dispatch('click', 'hello');
}
function handleType() {
dispatch('event');
dispatch('type', Math.random() > 0.5 ? 'world' : null);
}
</script>
<button on:click={handleClick} on:keydown={handleType}>Click</button>
ビルトインのDOM型を拡張するpermalink
Svelte はベストエフォートで存在する全ての HTML DOM の型を提供します。ときには実験的な属性やアクションから来るカスタムイベントを使いたい場合があるかもしれません。そのような場合には、TypeScript が型エラーを発生し、未知の型であると報告します。もし実験的ではない標準の属性やイベントであるなら、Svelte の HTML 型 から来た型付けの誤りによる可能性があります。その場合、issue や修正の PR を歓迎します。
これがカスタムまたは実験的な属性またはイベントの場合、以下のように型を拡張できます。
ts
declare namespacesvelteHTML {// 要素の拡張interfaceIntrinsicElements {'my-custom-element': {someattribute : string; 'on:event': (e :CustomEvent <any>) => void };}// 属性の拡張interfaceHTMLAttributes <T > {// on:beforeinstallprompt を使用したい場合'on:beforeinstallprompt'?: (event : any) => any;// myCustomAttribute={..} (注意: すべて小文字) を使用したい場合mycustomattribute ?: any; // 望むなら any をより特定の型に置き換えられます}}
そして、d.ts
ファイルが tsconfig.json
で参照されるようにします。"include": ["src/**/*"]
のような設定があり、d.ts
ファイルが src
内にあれば、上手く動作するはずです。変更を反映するためには再読み込みが必要なことがあります。
Svelte バージョン 4.2 / svelte-check
バージョン 3.5 / VS Code 拡張機能 107.10.0 以降では、以下のように svelte/elements
モジュールを拡張することでも型を宣言できるようになりました。
ts
import {HTMLButtonAttributes } from 'svelte/elements';declare module 'svelte/elements' {export interfaceSvelteHTMLElements {'custom-button':HTMLButtonAttributes ;}// 型を追加する要素へのより細かい制御を可能にするexport interfaceHTMLButtonAttributes {veryexperimentalattribute ?: string;}}export {}; // これが ambient module ではなく、他の型が拡張される代わりに上書きされることを保証する
実験的な高度な型付けpermalink
特定のインターフェイスを実装するコンポーネントの型付け、明示的に型付けされた slot、ジェネリクスの使用など、より高度なユースケースで TypeScript を最大限に活用するには、いくつかの機能が欠けています。これらの機能は、実験的な高度な型機能を利用することで実現可能です。使用方法に関するより詳しい情報は、この RFC を参照してください。
API は実験的であるため、いつでも変更される可能性があります
制限事項permalink
マークアップ内ではTSは使えないpermalink
TypeScript はテンプレートのマークアップ内では使えません。たとえば、次のコードは機能しません。
<script lang="ts">
let count = 10;
</script>
<h1>Count as string: {count as string}!</h1> <!-- ❌ 動かない -->
{#if count > 4}
{@const countString: string = count} <!-- ❌ 動かない -->
{countString}
{/if}
リアクティブな宣言permalink
TypeScript を使用したリアクティブな宣言に対しては、変数と同じように型付けすることはできません。たとえば、次のコードは動作しません。
<script lang="ts">
let count = 0;
$: doubled: number = count * 2; // ❌ 動かない
</script>
この位置では無効な構文となるため、: TYPE
を追加することはできません。その代わり、型の定義を直前の let
文に移動できます。
<script lang="ts">
let count = 0;
let doubled: number;
$: doubled = count * 2;
</script>
Typespermalink
ComponentConstructorOptionspermalink
ts
interface ComponentConstructorOptions<Props extends Record<string, any> = Record<string, any>> {…}
ts
target: Element | Document | ShadowRoot;
ts
anchor?: Element;
ts
props?: Props;
ts
context?: Map<any, any>;
ts
hydrate?: boolean;
ts
intro?: boolean;
ts
$$inline?: boolean;
ComponentEventspermalink
Convenience type to get the events the given component expects. Example:
<script lang="ts">
import type { ComponentEvents } from 'svelte';
import Component from './Component.svelte';
function handleCloseEvent(event: ComponentEvents<Component>['close']) {
console.log(event.detail);
}
</script>
<Component on:close={handleCloseEvent} />
ts
type ComponentEvents<Component extends SvelteComponent_1> =Component extends SvelteComponent<any, infer Events>? Events: never;
ComponentPropspermalink
Convenience type to get the props the given component expects. Example:
<script lang="ts">
import type { ComponentProps } from 'svelte';
import Component from './Component.svelte';
const props: ComponentProps<Component> = { foo: 'bar' }; // Errors if these aren't the correct props
</script>
ts
type ComponentProps<Component extends SvelteComponent_1> =Component extends SvelteComponent<infer Props>? Props: never;
ComponentTypepermalink
Convenience type to get the type of a Svelte component. Useful for example in combination with
dynamic components using <svelte:component>
.
Example:
<script lang="ts">
import type { ComponentType, SvelteComponent } from 'svelte';
import Component1 from './Component1.svelte';
import Component2 from './Component2.svelte';
const component: ComponentType = someLogic() ? Component1 : Component2;
const componentOfCertainSubType: ComponentType<SvelteComponent<{ needsThisProp: string }>> = someLogic() ? Component1 : Component2;
</script>
<svelte:component this={component} />
<svelte:component this={componentOfCertainSubType} needsThisProp="hello" />
ts
type ComponentType<Component extends SvelteComponent = SvelteComponent> = (new (options: ComponentConstructorOptions<Component extends SvelteComponent<infer Props>? Props: Record<string, any>>) => Component) & {/** The custom element version of the component. Only present if compiled with the `customElement` compiler option */element?: typeof HTMLElement;};
SvelteComponentpermalink
Base class for Svelte components with some minor dev-enhancements. Used when dev=true.
Can be used to create strongly typed Svelte components.
Example:permalink
You have component library on npm called component-library
, from which
you export a component called MyComponent
. For Svelte+TypeScript users,
you want to provide typings. Therefore you create a index.d.ts
:
ts
import {SvelteComponent } from "svelte";export classMyComponent extendsSvelteComponent <{foo : string}> {}
Typing this makes it possible for IDEs like VS Code with the Svelte extension to provide intellisense and to use the component like this in a Svelte file with TypeScript:
<script lang="ts">
import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
ts
class SvelteComponent<Props extends Record<string, any> = any,Events extends Record<string, any> = any,Slots extends Record<string, any> = any> extends SvelteComponent_1<Props, Events> {…}
ts
[prop: string]: any;
ts
constructor(options: ComponentConstructorOptions<Props>);
ts
$capture_state(): void;
ts
$inject_state(): void;
SvelteComponentTypedpermalink
Use
SvelteComponent
instead. See PR for more information: https://github.com/sveltejs/svelte/pull/8512
ts
class SvelteComponentTyped<Props extends Record<string, any> = any,Events extends Record<string, any> = any,Slots extends Record<string, any> = any> extends SvelteComponent<Props, Events, Slots> {}