Zodを活用した実践的なユースケースをいくつか紹介

Zodは基本的なバリデーションにとどまらず、複雑な型構造の検証や型共有、ユニオン型の条件付き分岐などにも対応可能です。
今回はより実践的なユースケースを紹介しながら、Zodの柔軟性と強力さを掘り下げていきます。
条件に応じた動的スキーマ分岐(Discriminated Union)
Zodでは条件付きのバリデーション分岐が可能です。これは、入力の内容に応じて構造が異なるフォームやAPIリクエストに非常に便利です。
tsconst AnimalSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal("dog"),
barkVolume: z.number(),
}),
z.object({
type: z.literal("cat"),
lives: z.number(),
}),
]);
type Animal = z.infer<typeof AnimalSchema>;
tsAnimalSchema.parse({ type: "dog", barkVolume: 10 }); // OK
AnimalSchema.parse({ type: "cat", lives: 9 }); // OK
AnimalSchema.parse({ type: "cat", barkVolume: 10 }); // ❌ ValidationError
「type」の値によってスキーマが切り替わるため、構造が分岐するデータの検証にぴったりです。
バックエンドとフロントエンドでの型共有
API設計で特に効果を発揮するのがスキーマと型の共通管理です。
Zodのスキーマ定義を共通パッケージにまとめ、両者で型とバリデーションを再利用できます。
例:共通パッケージ構成
bash/packages/shared-schema
└ user.ts ← zodスキーマと型定義
/frontend
└ 使用:フォームの入力チェック、型定義
/backend
└ 使用:リクエストバリデーション、レスポンス構築
共通スキーマ(shared-schema/user.ts)
tsimport { z } from "zod";
export const userSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1),
email: z.string().email(),
});
export type User = z.infer<typeof userSchema>;
このようにしておけば、型崩れや重複定義を防ぎ、保守性と安全性が大幅に向上します。
入れ子構造のバリデーションと型推論
Zodではネスト構造もシンプルに記述できます。
以下はブログ記事とタグの入れ子構造の例です。
tsconst tagSchema = z.object({
id: z.string(),
label: z.string(),
});
const articleSchema = z.object({
title: z.string(),
content: z.string().min(20),
tags: z.array(tagSchema),
});
このような構造でも、z.infer<typeof articleSchema>
を使えば深い階層の型推論が正確に行われるため、IDE補完の精度も非常に高まります。
.transform
を使った入力変換
Zodでは、バリデーションと同時に値の変換処理も可能です。
tsconst priceSchema = z
.string()
.transform((val) => parseFloat(val));
const result = priceSchema.parse("123.45"); // result: number型の123.45
APIやフォーム入力で「文字列で渡ってくるけど数値として使いたい」といった場合にも対応可能です。
.refine
と.superRefine
によるカスタムルール
refine
は1つの値に対する制約、superRefine
は複数フィールドにまたがるバリデーションが行えます。
tsconst passwordSchema = z
.object({
password: z.string(),
confirmPassword: z.string(),
})
.superRefine((val, ctx) => {
if (val.password !== val.confirmPassword) {
ctx.addIssue({
path: ["confirmPassword"],
code: z.ZodIssueCode.custom,
message: "パスワードが一致しません",
});
}
});
このように、フィールド同士の整合性検証も柔軟に設計できます。
まとめ
Zodを活用した高度なユースケースでは、以下のような強力な機能を使いこなせます。
機能 | 活用シーン |
---|---|
Discriminated Union | typeなどの条件に応じた構造の切り替え |
型の共通化 | APIでの型・バリデーションの一元管理 |
.transform | 入力値の自動変換(例:文字列→数値) |
.superRefine | 複数項目の相関チェック(例:パスワード) |
これらを適切に活用することで、開発体験の向上、バグの削減、そして将来的な変更への強さが手に入ります。
Zodは型安全を保ちつつ、複雑な仕様にも耐えうる実用的なツールです。ぜひプロジェクトのコアに取り入れてみてください。
記事Article
もっと見る- article
NestJSでバリデーションエラーをログ出力する設定を紹介
- article
NestJSで作成したAPIのレスポンスヘッダーに付与されるx-powered-by: Express を消す方法を紹介
- article
Next.jsで環境変数に別の変数を利用し柔軟に管理するdotenv-expandの活用法を紹介
- article
【2025年3月版】Cursor ProとAPI利用比較。 Claude・GPT-4o・o1・GPT-4.5の損益分岐点と選び方
- article
フォーム入力情報からZodを利用してDTO作成しへ変換処理を実施するやり方を紹介
- article
Zodバリデーションのエラーメッセージを日本語化すやり方を紹介