はじめに
こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
TypeScript を使っていると、型定義と入力値のバリデーションを別々に書かないといけない問題があります。
例えばフォーム入力や API レスポンスのチェックを全部手動でやるのは面倒だし、ミスも起きやすい…。
そこで便利なのが Zod です。
Zod を使うと、型定義とバリデーションを 1 つのスキーマで表現でき、実行時の安全性も確保できます。
Zod とは?
- 型安全なスキーマ定義&バリデーションライブラリ
- ランタイムでも型を保証できるのが大きな特徴
- スキーマを定義すると、そのまま TypeScript の型として推論できる
インストール
npm install zod
基本的な使い方
スキーマ定義とバリデーション
import { z } from 'zod';
const userSchema = z.object({
name: z.string(),
age: z.number().min(0).max(120),
});
userSchema.parse({ name: 'Taro', age: 25 }); // ✅ OK
userSchema.parse({ name: 'Hanako', age: -5 }); // ❌ エラー
型の推論
type User = z.infer<typeof userSchema>;
// => { name: string; age: number }
よく使うスキーマ
-
z.string().min(n).max(n)
→ 文字列の長さ制約 -
z.number().int().positive()
→ 整数・正の数 -
z.enum(["admin", "user"])
→ 定数リストから選択 -
z.array(z.string())
→ 配列 -
z.optional(z.string())
→ 任意項目
エラーメッセージのカスタマイズ
Zod はバリデーションごとに message
を設定できます。ユーザー向けのわかりやすいフィードバックが可能です。
const formSchema = z.object({
email: z
.string()
.email({ message: '正しいメールアドレスを入力してください' }),
password: z
.string()
.min(8, { message: 'パスワードは8文字以上で入力してください' }),
});
const result = formSchema.safeParse({
email: 'invalid-email',
password: 'short',
});
if (!result.success) {
console.log(result.error.format());
// {
// email: { _errors: ["正しいメールアドレスを入力してください"] },
// password: { _errors: ["パスワードは8文字以上で入力してください"] }
// }
}
実践例
フォーム入力のチェック
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
const result = formSchema.safeParse({
email: 'test@example.com',
password: 'short',
});
if (!result.success) {
console.log(result.error.format());
}
API レスポンスのバリデーション
const apiSchema = z.object({
id: z.number(),
title: z.string(),
});
fetch('/api/post/1')
.then((res) => res.json())
.then((data) => {
const parsed = apiSchema.parse(data); // レスポンスを型安全に利用
console.log(parsed.title);
});
Zod を使うメリット
- バリデーションと型定義を一元管理できる
- TypeScript の型を自動で推論してくれる
- エラーメッセージをカスタマイズ可能
- API レスポンスやフォームチェックにそのまま使える
まとめ
- Zod は 「型定義」+「ランタイムバリデーション」 を同時に解決してくれる便利なライブラリ
- 最初は
object
,string
,number
あたりから始めるのがおすすめ