TypeScript検証ライブラリ

Zodを選ぶ理由

TypeScriptの「盲点」を補完し、実行時の安全性を確保するスキーマ検証ライブラリの仕組みと、類似ライブラリとの比較

読了時間:約5分
1

TypeScriptだけでは守れないもの

TypeScriptは強力な型システムを提供しますが、根本的な制約があります。それはコンパイル時(書いている時)にしか型チェックが行われないということです。

TypeScriptの型チェックが機能するタイミング

コード作成
型チェック有効
コンパイル
型チェック有効
JavaScript生成
型情報が消滅
実行時
保護なし

問題は、アプリケーションが外部からデータを受け取る場面で発生します。APIレスポンス、ユーザー入力、設定ファイルなど、外部から来るデータの構造は実行時まで分からないためです。

TypeScriptだけの場合
problem.ts
interface User {
  name: string;
  age: number;
}

// APIからデータを取得
const res = await fetch('/api/user');
const user: User = await res.json();

// 型は正しいはず... でも実際は?
console.log(user.name.toUpperCase());
// 💥 実行時エラー: nameがundefined

TypeScriptは「APIがUserの形式を返す」と信じるだけです。実際に返ってきたデータの検証は行いません。

VS
Zodを使う場合
solution.ts
import { z } from 'zod';

const UserSchema = z.object({
  name: z.string(),
  age: z.number(),
});

const res = await fetch('/api/user');
const data = await res.json();
const user = UserSchema.parse(data);
// ✅ 検証済み&型安全

console.log(user.name.toUpperCase());
// 安心して使える

Zodは実行時にデータを検証し、不正なデータはエラーとして報告します。通過したデータは型安全です。

2

Zodの仕組み:1つの定義から2つの価値

Zodの核心的な価値は、スキーマ(データの設計図)を1つ定義するだけで、実行時の検証ルールとTypeScriptの型の両方を同時に得られることです。

「単一の定義源」(Single Source of Truth)

従来は「TypeScript用の型定義」と「検証用のルール」を別々に書く必要がありました。これは二重管理となり、ズレが生じるリスクがありました。Zodはこの問題を解決します。

Zodのデータフロー

1. スキーマを定義
z.object(), z.string(), z.number() などを組み合わせて、データの構造と制約を宣言的に記述します。
2. TypeScript型を自動推論
z.infer<typeof Schema> で、スキーマからTypeScriptの型を自動生成。手動での型定義が不要になります。
3. 実行時に検証
parse() または safeParse() でデータを検証。不正なデータはエラー情報と共に報告されます。
4. 型安全なデータを取得
検証を通過したデータは、TypeScriptが正しい型として認識。以降は安心して使用できます。
schema-example.ts - 実際の使用例
import { z } from 'zod';

// スキーマ定義(検証ルール + 型情報)
const UserSchema = z.object({
  email: z.string().email('有効なメールアドレスを入力してください'),
  age: z.number().min(18, '18歳以上である必要があります'),
  role: z.enum(['admin', 'user', 'guest']),
});

// 型を自動推論(手動定義不要)
type User = z.infer<typeof UserSchema>;
// → { email: string; age: number; role: 'admin' | 'user' | 'guest' }

// 検証(2つの方法)
const result = UserSchema.safeParse(unknownData);
if (result.success) {
  // result.data は型安全な User
  console.log(result.data.email);
} else {
  // result.error に詳細なエラー情報
  console.log(result.error.issues);
}
3

Zodの主要な特徴

ゼロ依存性

外部ライブラリに一切依存しません。脆弱性リスクが低く、バージョン管理が容易です。

TypeScriptファースト

TypeScriptを前提に設計されており、型推論が非常に強力です。JavaScriptでも使用可能です。

イミュータブル設計

.optional() や .extend() は新しいインスタンスを返し、元のスキーマを変更しません。予期しない副作用を防ぎます。

豊富なエコシステム

tRPC、React Hook Form、TanStack Routerなど、多くのライブラリとシームレスに連携できます。

詳細なエラーメッセージ

どのフィールドが、どの理由で失敗したか、パス情報と共に詳細に報告されます。カスタムメッセージも設定可能です。

データ変換

.transform() で検証と同時にデータ変換が可能。文字列を日付に変換するなど、入力→出力の型を変えられます。

39K+
GitHubスター
週1200万
npmダウンロード
0
依存関係
4

類似ライブラリとの比較

Zodは唯一の選択肢ではありません。用途や要件に応じて、他のライブラリが適している場合もあります。

ライブラリ TypeScript連携 バンドルサイズ 主な用途 特徴
Zod 優秀 ~13-45KB フルスタック 型推論が強力、エコシステム豊富
Valibot 優秀 ~1-5KB フロントエンド 最軽量、Zodと似たAPI
Yup 良好 ~60KB フォーム検証 Formikと連携、歴史が長い
Joi 要追加設定 ~150KB サーバーサイド 機能が豊富、複雑な検証向け
AJV 要追加設定 ~85KB 高性能API 最速、JSON Schema準拠

ライブラリの位置づけマップ

TypeScript連携:強い TypeScript連携:弱い シンプル 高機能
Zod
Valibot
Yup
Joi
AJV
Zodの制約
バンドルサイズ:Valibotの最大10倍。クライアントサイドのみの軽量アプリケーションでは、Valibotが適している場合があります。
性能:.extend() や .pick() を多用すると性能が低下する報告があります。AJVは純粋な検証速度では最速です。
複雑な検証:非常に複雑な条件付き検証では、Joiの方が表現力が高い場合があります。
5

Zodのエコシステム

Zodは単体でも強力ですが、他のツールと組み合わせることで真価を発揮します。特にフロントエンドからバックエンドまで同じスキーマを共有できるのが大きな利点です。

🔗
tRPC
型安全なAPI通信。Zodスキーマで入出力を定義
📝
React Hook Form
zodResolverでフォーム検証を統合
🛣️
TanStack Router
ルートパラメータの型安全な検証
🗄️
Prisma
DBスキーマからZodスキーマを生成
⚙️
Next.js
Server Actionsとの組み合わせ
📋
OpenAPI
zod-to-openapi でAPI仕様書を生成
tRPC + Zod の例:フロントエンドとバックエンドで同じスキーマを共有
// server/router.ts(バックエンド)
const CreatePostSchema = z.object({
  title: z.string().min(1),
  content: z.string(),
});

export const postRouter = router({
  create: publicProcedure
    .input(CreatePostSchema)  // ← Zodスキーマで入力を検証
    .mutation(({ input }) => {
      // input は型安全な { title: string, content: string }
      return db.post.create({ data: input });
    }),
});

// client/form.tsx(フロントエンド)
const { mutate } = trpc.post.create.useMutation();
// mutateの引数は自動的に { title: string, content: string } と推論される
6

どのライブラリを選ぶべきか

プロジェクトの要件に応じて、最適なライブラリは異なります。以下のフローチャートを参考にしてください。

TypeScriptを使用していますか?
はい いいえ → Joiを検討
バンドルサイズが最重要ですか?(クライアントサイドのみのアプリなど)
はい → Valibot いいえ
tRPC、React Hook Form、Next.jsなどと連携しますか?
はい → Zod(エコシステム最強) いいえ
極めて複雑な条件付き検証が必要ですか?
はい → Joi いいえ
最高の検証パフォーマンスが必要ですか?
はい → AJV いいえ → Zod(バランス最良)
多くの場合、Zodが最適解

TypeScriptとの統合、豊富なエコシステム、活発なコミュニティにより、ほとんどのTypeScriptプロジェクトでZodは良い選択です。ただし、特定の要件(極小バンドルサイズ、最高性能、複雑な検証)がある場合は、専門ライブラリを検討してください。