Standard Schema - TypeScriptバリデーションのための共通インターフェース
(standardschema.dev)- JavaScript/TypeScriptベースのスキーマライブラリが共通インターフェースを実装するよう設計された仕様
- ライブラリごとにユーザー定義の型検証ロジックを再利用できるようにし、ツール同士が個別のアダプターなしで相互運用できるようにするのが目的
- Zod、Valibot、ArkType など主要ライブラリの作者が共同で設計
主要インターフェース (StandardSchemaV1)
~standardというオブジェクトプロパティを通じて、すべての仕様を実装~standardの中にversion、vendor、validate、typesなどの必須プロパティが存在validate関数は成功時にvalueを、失敗時にissues配列を返すtypesプロパティにより、TypeScriptでスキーマの入力 (input) と出力 (output) の型を推論できる- すべてのアップデートは、メジャーバージョン変更でない限り互換性を維持
設計目標
- ランタイム検証のサポート: 標準方式でエラー情報を標準化して渡す
- 静的型推論のサポート: TypeScriptベースのライブラリが推論した型情報を明示的に公開
- 簡潔さ: 既存ライブラリ関数に数行追加するだけで実装可能
- API衝突の回避:
~standardという1つの名前空間にすべてを入れ、既存APIと衝突しないようにする - 開発者体験の維持:
~standardのようにチルダ (~) で始め、補完での優先順位を下げる
どのライブラリが実装しているか
- すでに Zod、Valibot、ArkType、Arri Schema、TypeMap などで Standard Schema をサポート
- tRPC、TanStack Form、TanStack Router、Hono Middleware なども Standard Schema をベースにユーザースキーマを受け入れている
自分のライブラリに仕様を実装する方法
StandardSchemaV1インターフェースをライブラリにコピーし、~standardプロパティを追加するvalidate関数を既存の検証関数に接続し、成功時は{ value }、失敗時は{ issues }を返すようにする- 必要に応じて非同期検証も可能だが、同期検証を推奨
Standard Schema でユーザー定義スキーマを受け取る方法
- スキーマライブラリなしで直接使うには、
@standard-schema/specをインストールするか、インターフェースをコピーして使う - 例の関数
standardValidateのように、標準インターフェースを持つスキーマであれば、どのライブラリでも同じ方法でバリデーション可能 - 同期検証だけを許可する場合は、
validateの返り値がPromiseかどうかを確認してから例外処理を行えばよい
FAQ
@standard-schema/specの依存関係を追加する必要はあるか?: 必ずしも依存関係として追加する必要はなく、コピーして使用できる- dev dependency としては追加不可: ライブラリのパブリックAPIになるため、実際の配布環境でも利用可能である必要がある
~standardの前にチルダ (~) を使った理由: 補完で他のプロパティより後ろに表示されるよう意図している- Symbol ではなく文字列キーを使った理由: TypeScriptでSymbolキーを使うと、補完順や型推論で問題が起きるため
まだコメントはありません。