【TypeScript】Zodを使用した実行時の型検証入門 - 型安全なデータバリデーション

【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を活用し、型安全なデータバリデーションを実現しましょう。

Recommend