
こんにちは。よっしーです(^^)
今日は、SvelteKitのリファレンスについて解説しています。
背景
SvelteKitのリファレンスについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
@sveltejs/kit
SubmitFunction
type SubmitFunction
Success extends
| Record<string, unknown>
| undefined = Record<string, any>,
Failure extends
| Record<string, unknown>
| undefined = Record<string, any>
> = (input: {
action: URL;
formData: FormData;
formElement: HTMLFormElement;
controller: AbortController;
submitter: HTMLElement | null;
cancel: () => void;
}) => MaybePromise
| void
| ((opts: {
formData: FormData;
formElement: HTMLFormElement;
action: URL;
result: ActionResult<Success, Failure>;
/**
* フォーム送信レスポンスのデフォルトの動作を取得するには、これを呼び出します。
* @param options 成功した送信後に`<form>`の値をリセットしたくない場合は`reset: false`を設定します。
* @param invalidateAll 送信後にアクションが`invalidateAll`を呼び出さないようにしたい場合は`invalidateAll: false`を設定します。
*/
update: (options?: {
reset?: boolean;
invalidateAll?: boolean;
}) => Promise<void>;
}) => MaybePromise<void>)
>;
解説
SubmitFunction
は、SvelteKitにおけるフォーム送信処理をカスタマイズするための型定義です。この型は、フォーム送信時の動作を制御するコールバック関数の構造を定義しています。
型パラメータ
Success
: 成功したアクションの結果の型。デフォルトはRecord<string, any>
Failure
: 失敗したアクションの結果の型。デフォルトはRecord<string, any>
入力パラメータ (input)
関数は次のプロパティを持つオブジェクトを受け取ります:
action
: フォームの送信先URLformData
: 送信されるフォームデータformElement
: 送信されるHTMLフォーム要素controller
: リクエストをキャンセルするために使用できるAbortController
submitter
: フォーム送信を開始した要素(例:送信ボタン)cancel
: フォーム送信をキャンセルするための関数
戻り値
この関数は以下のいずれかを返すことができます:
void
– 処理を継続し、デフォルトの動作を実行- コールバック関数 – フォーム送信処理の結果を受け取り、追加の処理を行う関数
このコールバック関数は以下のパラメータを受け取ります:
formData
: 送信されたフォームデータformElement
: フォーム要素action
: 送信先URLresult
: アクションの結果(Success
またはFailure
型)update
: デフォルトの送信後処理を実行する関数reset
: 成功時にフォームをリセットするかどうか(デフォルトはtrue
)invalidateAll
: 送信後に全てのデータを再検証するかどうか(デフォルトはtrue
)
使用例
この型は、SvelteKitのuse:enhance
ディレクティブなどで使用され、フォーム送信の挙動をプログラムで制御できます。例えば:
<form
method="POST"
use:enhance={({ formData, cancel }) => {
// 送信前の検証
if (!isValid(formData)) {
cancel();
return;
}
// 送信後の処理
return ({ result, update }) => {
if (result.type === 'success') {
// 成功時の追加処理
showSuccessMessage();
// デフォルト処理を実行(フォームリセットなど)
return update();
} else {
// エラー処理
showErrorMessage(result.error);
// フォームをリセットせずにデータ再検証
return update({ reset: false });
}
};
}}
>
<!-- フォーム内容 -->
</form>
この型定義により、SvelteKitアプリケーションでフォーム送信の前後に詳細なカスタム処理を追加できます。
Transport
バージョン2.11.0以降で利用可能
transport
フックを使用すると、サーバー/クライアント境界を越えてカスタム型を転送できます。 各トランスポーターは、encode
とdecode
関数のペアを持っています。サーバー側では、encode
は値がカスタム型のインスタンスであるかどうかを判断し、そうであれば、オブジェクトまたは配列になり得る、その値の非偽のエンコーディングを返します(そうでなければfalse
を返します)。 ブラウザでは、decode
がエンコーディングをカスタム型のインスタンスに戻します。
import type { Transport } from '@sveltejs/kit';
declare class MyCustomType {
data: any
}
// hooks.js
export const transport: Transport = {
MyCustomType: {
encode: (value) => value instanceof MyCustomType && [value.data],
decode: ([data]) => new MyCustomType(data)
}
};
type Transport = Record<string, Transporter>;
解説
Transport
は、SvelteKit 2.11.0から導入された機能で、サーバーとクライアント間でカスタムJavaScriptクラスや型のインスタンスをシームレスに転送するためのメカニズムを提供します。
主要な概念
- 問題の背景: 通常、サーバーサイドレンダリング(SSR)やロード関数からクライアントに値を渡す際、JSON.stringifyを通してシリアライズされます。これは基本的なデータ型(オブジェクト、配列、プリミティブ値)には機能しますが、カスタムクラスのインスタンスなど複雑な型は適切に転送されません。
- Transportの役割: カスタムクラスやデータ型のインスタンスをサーバーからクライアントへ(またはその逆方向に)正しく転送するための変換ロジックを定義します。
使用方法
Transport
は、次の2つの関数を持つトランスポーターオブジェクトをキーと値のペアとして格納するレコード型です:
encode
関数: サーバー側で実行され、値がカスタム型のインスタンスかどうかを判断します- カスタム型のインスタンスであれば、そのデータを表す配列またはオブジェクトを返します
- そうでなければ、
false
を返します
decode
関数: クライアント側で実行され、エンコードされたデータを元のカスタム型のインスタンスに変換します
実装例の解説
export const transport: Transport = {
MyCustomType: { // キーはトランスポーターの名前
// サーバー側でMyCustomTypeインスタンスを識別してエンコード
encode: (value) => value instanceof MyCustomType && [value.data],
// クライアント側でエンコードされたデータからMyCustomTypeインスタンスを再構築
decode: ([data]) => new MyCustomType(data)
}
};
実用例
このフックは以下のような場面で特に役立ちます:
- 日付オブジェクト:
Date
オブジェクトをString型ではなく実際のDateインスタンスとしてクライアントに渡す - カスタムクラス: データモデルのインスタンスをメソッドも含めてクライアントに転送する
- 特殊なデータ型:
Map
やSet
など、JSONでは直接シリアライズできない型を転送する
設定場所
このtransport
フックは通常、SvelteKitアプリケーションのhooks.js
(またはhooks.ts
)ファイルで定義され、アプリケーション全体でカスタム型の変換ロジックが一貫して適用されるようにします。
この機能によって、サーバーとクライアント間でのデータ転送が大幅に簡素化され、アプリケーションのコードがより自然に書けるようになります。
Transporter
transport
フックのメンバー。
interface Transporter
T = any,
U = Exclude
any,
false | 0 | '' | null | undefined | typeof NaN
>
> {…}
encode: (value: T) => false | U;
decode: (data: U) => T;
解説
Transporter
インターフェースは、SvelteKitのtransport
フックの各メンバーを定義するものです。このインターフェースは、カスタム型のインスタンスをサーバーとクライアント間で変換するための方法を提供します。
型パラメータ
T
: 変換する対象となるカスタム型。デフォルトはany
U
: エンコードされた値の型。デフォルトでは偽値(false
,0
,''
,null
,undefined
,NaN
)以外のあらゆる値が許容されます
encode: (value: T) => false | U
- 目的: サーバー側で、値がカスタム型
T
のインスタンスかどうかを判断し、インスタンスである場合はシリアライズ可能な形式にエンコードします - 引数: カスタム型
T
の可能性のある値 - 戻り値:
- 値が対象のカスタム型
T
のインスタンスである場合: エンコードされたデータ(U
型) - 値が対象のカスタム型
T
のインスタンスでない場合:false
- 値が対象のカスタム型
- 注意: エンコード結果はJSONシリアライズ可能である必要があります(通常は配列やプレーンオブジェクト)
decode: (data: U) => T
- 目的: クライアント側で、エンコードされたデータ
U
を元のカスタム型T
のインスタンスに変換します - 引数:
encode
関数によって生成されたエンコードデータ(U
型) - 戻り値: 復元されたカスタム型
T
のインスタンス
使用例
例えば、Point
というカスタムクラスがあり、これをサーバーとクライアント間で転送したい場合:
class Point {
constructor(public x: number, public y: number) {}
distanceFromOrigin() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
}
// hooks.js/ts に定義するtransportフック
export const transport = {
Point: {
encode: (value) => value instanceof Point && [value.x, value.y],
decode: ([x, y]) => new Point(x, y)
}
};
この例では:
encode
関数は値がPoint
のインスタンスである場合にxとy座標を配列として返しますdecode
関数はその配列から新しいPoint
インスタンスを作成します
これにより、サーバー側のロード関数から返されたPoint
オブジェクトが、クライアント側でもメソッドを含む完全なPoint
インスタンスとして利用できるようになります。
おわりに
今日は、 SvelteKitのリファレンスについて解説しました。

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント