【TypeScript】Zodを使用した実行時の型検証入門 - 型安全なデータバリデーション
2024-11-10
2024-11-10
概要
TypeScript
での開発では型安全性を重視しますが、コンパイル時のみでなく、実行時にも型の検証が必要なケースがあります。例えば、APIレスポンスやユーザー入力など外部からのデータを扱う場合です。そんなときに役立つのがZod
です。Zodは、TypeScript
用の軽量なバリデーションライブラリで、実行時にデータの型検証を行い、安全なデータ処理を可能にします。本記事では、Zodの基本的な使い方と実践的な活用方法を紹介します。
Zodとは?
Zodは、TypeScript
で型安全なデータバリデーションを実行時に行うためのライブラリです。TypeScript
の型システムはコンパイル時にのみ型チェックを行うため、実行時に外部から取得したデータの型が保証されていないことがあります。Zodは、スキーマを定義して実行時にデータの型を検証することで、TypeScript
と組み合わせて安全なデータ処理を実現します。
Zodのインストール
まず、Zodをプロジェクトにインストールします。
npm install zod
基本的な使い方
単純な型検証
Zodで単純なデータの型検証を行うには、z
から基本型をインポートし、スキーマを定義します。例えば、文字列や数値の検証は以下のように行います。
import { z } from "zod";
const nameSchema = z.string();
const ageSchema = z.number();
const name = nameSchema.parse("Alice"); // 検証成功: "Alice"
const age = ageSchema.parse(30); // 検証成功: 30
// 検証失敗例
try {
nameSchema.parse(123); // エラー: expected string, received number
} catch (error) {
console.error(error.errors);
}
.parse()
メソッドは、引数のデータがスキーマに適合しているかを検証します。不一致の場合はエラーが発生し、詳細なエラーメッセージが表示されます。
オブジェクトの型検証
Zodの強力な特徴は、複雑なオブジェクトのスキーマを定義できる点です。例えば、ユーザーオブジェクトのスキーマを定義する場合、以下のように行います。
const userSchema = z.object({
name: z.string(),
age: z.number().int().positive(),
email: z.string().email(),
});
const user = userSchema.parse({
name: "Alice",
age: 30,
email: "alice@example.com"
}); // 検証成功
// 検証失敗例
try {
userSchema.parse({
name: "Alice",
age: -5, // 不正な年齢
email: "invalid-email"
});
} catch (error) {
console.error(error.errors);
}
オブジェクトの各プロパティに対して、型やルールを定義できます。上記の例では、age
プロパティに正の整数であることを要求し、email
は有効なメール形式であることを検証します。
実践的なZodの活用方法
ネストされたオブジェクトの検証
Zodでは、ネストされたオブジェクトも簡単に定義できます。たとえば、住所情報を持つユーザーのスキーマを次のように作成します。
const addressSchema = z.object({
street: z.string(),
city: z.string(),
postalCode: z.string().regex(/^\d{5}$/),
});
const userWithAddressSchema = z.object({
name: z.string(),
age: z.number().int().positive(),
address: addressSchema,
});
const user = userWithAddressSchema.parse({
name: "Bob",
age: 28,
address: {
street: "123 Main St",
city: "Hometown",
postalCode: "12345"
}
}); // 検証成功
このように、address
フィールドにaddressSchema
を割り当てることで、入れ子構造のデータも型安全に検証できます。
配列の検証
配列の検証も簡単です。例えば、ユーザーのリストを検証する場合、以下のようにスキーマを定義します。
const userListSchema = z.array(userSchema);
const users = userListSchema.parse([
{ name: "Alice", age: 25, email: "alice@example.com" },
{ name: "Bob", age: 30, email: "bob@example.com" }
]); // 検証成功
配列内の各要素がuserSchema
に適合しているかを確認できるため、データの一貫性を保つことが可能です。
Union型による複数の型の許容
ZodのUnion型を使えば、複数の異なる型を許容するスキーマも定義できます。たとえば、ユーザーが管理者か一般ユーザーかで異なるデータ構造を持つ場合、Union型を使用します。
const adminSchema = z.object({
role: z.literal("admin"),
permissions: z.array(z.string()),
});
const userSchema = z.object({
role: z.literal("user"),
preferences: z.object({
theme: z.string(),
}),
});
const memberSchema = z.union([adminSchema, userSchema]);
const admin = memberSchema.parse({
role: "admin",
permissions: ["read", "write"]
}); // 検証成功
const user = memberSchema.parse({
role: "user",
preferences: { theme: "dark" }
}); // 検証成功
z.union()
を使うことで、異なる型のデータを許容し、条件に応じた型の検証が可能です。
エラー処理のカスタマイズ
Zodの.safeParse()
メソッドを使うと、エラーが発生しても例外をスローせず、エラーメッセージを含むオブジェクトを返します。これにより、エラー処理を柔軟に行えます。
const result = userSchema.safeParse({
name: "Alice",
age: -5, // 不正な値
email: "invalid-email"
});
if (!result.success) {
console.error("Validation failed:", result.error.format());
} else {
console.log("Validation succeeded:", result.data);
}
このように、safeParse
メソッドは検証結果に応じて柔軟にエラーメッセージを処理でき、UIの表示やエラーログの記録に役立ちます。
TypeScriptの型推論とZodの連携
Zodを使ってスキーマを定義
すると、TypeScript
の型推論と連携し、スキーマから自動的に型が生成されます。Zodのinfer
メソッドでスキーマから型を取得し、コードの一貫性と型安全性を保つことが可能です。
const productSchema = z.object({
id: z.string(),
name: z.string(),
price: z.number().positive(),
});
type Product = z.infer<typeof productSchema>;
const product: Product = {
id: "123",
name: "Example Product",
price: 100,
};
z.infer<typeof productSchema>
により、Product
型が自動的に定義されるため、重複する型定義を避け、スキーマの変更があっても型が自動で同期されます。
まとめ
Zod
は、TypeScript
と組み合わせて実行時の型検証を行うための便利なライブラリです。外部データの検証や、型安全なエラーハンドリングを簡潔に行えるため、アプリケーションの堅牢性が向上します。単純な型の検証から複雑なネスト構造やユニオン型の利用まで、Zodを活用することで、実行時のエラーを未然に防ぎ、安全なデータ処理が実現できます。Zodを活用し、型安全なデータバリデーションを実現しましょう。