zod について
Zod は、同じスキーマから実行時の検証と TypeScript の静的型推論を得られる、TypeScript 向けのスキーマ検証ライブラリです。外部依存なしで、解析、絞り込み、変換、スキーマの組み合わせに対応します。
主な機能
- 01実行時検証と TypeScript 型推論
- 02オブジェクト、配列、タプル、ユニオンのスキーマ構成
- 03条件検証とデータ変換
- 04同期・非同期の解析
- 05詳細な検証エラー
活用シーン
- 01アプリケーション境界での API データ検証
- 02環境変数や信頼できない入力の確認
- 03型推論を伴うフォームスキーマの定義
- 04解析データの変換と検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ enderpuentes/ ai-agent-skills --skill zodインストール後、Claude Code で/zodを入力して読み込まれたか確認します。
同梱ファイルLICENSE.mdreference.md
詳細
Zod
概要
Zod は、静的型推論に対応した TypeScript ファーストのスキーマ検証ライブラリです。スキーマを一度定義すれば、実行時の検証と TypeScript の型(z.infer 経由)の両方を利用できます。外部依存関係はゼロで、Node とブラウザーで動作します。フォーム(react-hook-form との連携など)、API の解析、環境変数、その他信頼できない入力全般に適しています。
要件:TypeScript 5.5 以降を推奨します。tsconfig.json で strict を有効にしてください。
インストール:パッケージマネージャーを使って zod を追加してください。zod.dev をご覧ください。
クイックスタート
import { z } from "zod";
const User = z.object({
name: z.string(),
age: z.number().optional(),
});
type User = z.infer<typeof User>;
// { name: string; age?: number }
const data = User.parse(input); // throws ZodError if invalid
const result = User.safeParse(input); // { success: true, data } | { success: false, error }
プリミティブ型とよく使う型
| スキーマ | 型 | 備考 |
|---|---|---|
z.string() | string | |
z.number() | number | |
z.boolean() | boolean | |
z.bigint() | bigint | |
z.date() | Date | |
z.undefined() | undefined | |
z.null() | null | |
z.void() | void | |
z.any() | any | |
z.unknown() | unknown | |
z.never() | never | |
z.literal("x") | literal | |
z.enum(["a", "b"]) | union of literals | |
z.string().email() | string | メールアドレス形式 |
z.string().url() | string | URL |
z.string().uuid() | string | UUID |
z.string().datetime() | string | ISO 日時 |
z.number().int() | number | 整数 |
z.number().min(n).max(m) | number | 範囲 |
z.boolean() / z.string().transform(...) | stringbool | "true"/"false" の強制変換 |
省略可能:.optional() → T | undefined。Nullable:.nullable() → T | null。Nullish:.nullish() → T | null | undefined。デフォルト値:.default(value)。
オブジェクト
const Schema = z.object({
name: z.string(),
age: z.number().optional(),
tags: z.array(z.string()).default([]),
});
type Schema = z.infer<typeof Schema>;
- .shape:
Schema.shape.name(フィールドのスキーマにアクセスします)。 - .keyof():
Schema.keyof()→ キーの列挙型。 - .extend({ ... }):キーを追加または上書きします。
- .pick({ name }) / .omit({ age }):キーのサブセットを指定します。
- .partial() / .required({ name }):省略可能にする、または必須にします。
- .strict():余分なキーを許可しません(
z.objectのデフォルト)。動作の異なる z.strictObject / z.looseObject もあります。 - .catchall(z.string()):スキーマを指定して余分なキーを許可します。
- ネスト:
z.object({ user: z.object({ name: z.string() }) })。 - 再帰:自己参照構造には
z.lazy(() => Category)を使います。
配列とタプル
- 配列:
z.array(z.string())、z.string().array()。 - タプル:
z.tuple([z.string(), z.number()])— 長さと型が固定されています。 - 空でない配列:
.min(1)または利用可能な専用ヘルパーを使います。
ユニオンとインターセクション
- ユニオン:
z.union([z.string(), z.number()])またはz.string().or(z.number())。 - 判別可能なユニオン:共通キー(例:
type: "a")を使い、z.discriminatedUnion("type", [z.object({ type: z.literal("a"), ... }), ...])を指定します。 - インターセクション:
z.intersection(A, B)またはA.and(B)。
リファインメントと変換
- .refine(fn, message?):カスタム検証を行います。型は変わりません。
- .superRefine:複数の問題を報告する場合や非同期処理に対応します。
ctxに追加します。 - .transform(fn):出力型を変更します。入力と出力で型が異なる場合があります。
z.input<typeof schema>とz.output<typeof schema>を使います(出力型にはz.inferも使えます)。 - .pipe(otherSchema):検証や変換を連結します(例:
z.string().pipe(z.coerce.number())で文字列を数値に変換)。
解析とエラー
- .parse(input):データを返すか、ZodError をスローします。
- .safeParse(input):
{ success: true, data }または{ success: false, error: ZodError }を返します。 - ZodError:
error.issues({ path, message, code }の配列)、ネストした形状を取得するにはerror.format()を使います。 - 非同期:非同期のリファインメントや変換を含むスキーマには、
.parseAsync/.safeParseAsyncを使います。
型推論
- z.infer:出力型(変換やデフォルト値の適用後)。
- z.input:入力型(変換前。入力と出力が異なる場合に便利です)。
- z.output:出力型。
z.inferと同じです。
const S = z.string().transform((s) => s.length);
type In = z.input<typeof S>; // string
type Out = z.output<typeof S>; // number
連携:React Hook Form
zodResolver と @hookform/resolvers を使います。
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormValues = z.infer<typeof formSchema>;
const form = useForm<FormValues>({
resolver: zodResolver(formSchema),
defaultValues: { email: "", password: "" },
});
ベストプラクティス
- API の境界では厳格なスキーマ(余分なキーを許可しない)を優先してください。不明なキーを転送する必要がある場合にのみ .passthrough() を使用してください。
- デフォルト値のある任意フィールドには .default() を使用してください。
- API/環境変数のパースには safeParse を使用してエラーを処理し、
error.issuesからユーザーにわかりやすいメッセージを表示してください。 - バリアントごとに異なるペイロード(例:
typeによるイベント)には判別可能なユニオンを使用してください。 - 安全な場合に限り、型を強制してください:
z.coerce.number()、z.coerce.boolean()、またはカスタムの.transform()を使用してください。
よくある間違い
- strict の設定を忘れる:TypeScript の
strict: trueを維持してください。Zod はこれを設定した状態で最も効果的に機能します。 - 入力と出力の違い:
.transform()の後で、呼び出し元から見える型が異なる場合はz.input<>/z.output<>を使用してください。 - ホットパスでの parse:レンダリングのたびに検証するのではなく、境界(例:API ハンドラー、フォーム送信時)で一度だけ検証することを優先してください。
- 広すぎるスキーマ:ドメインにルールがある場合は、単なる
z.string()ではなく、.email()や.min()などの具体的な型を優先してください。
その他のリソース
- reference.md — Zod の公式ドキュメントへのリンク、API の各セクション(プリミティブ、オブジェクト、文字列、数値、リファインメントなど)、Zod Mini、エコシステム。
- 公式:https://zod.dev — 概要、API、基本、エコシステム。
- API(Zod 4):https://zod.dev/api — スキーマの型とメソッドの全一覧。
- LLM/インデックス:https://zod.dev/llms.txt — ツール/エージェント向けの構造化ドキュメント。
コメント
Markdown 対応