T-CREATOR

Zod クイックリファレンス:`string/number/boolean/date/enum/literal` 速見表

Zod クイックリファレンス:`string/number/boolean/date/enum/literal` 速見表

TypeScript でのランタイムバリデーションを実現する Zod ライブラリは、型安全性を保ちながら効率的なデータ検証を可能にします。その中でも基本型(プリミティブ型)は、あらゆるスキーマ定義の土台となる重要な要素です。本記事では、Zod の 6 つの基本型について、それぞれの特徴と具体的な使用方法を体系的にご紹介します。

背景

Zod とは何か

Zod は、TypeScript ファーストなスキーマバリデーションライブラリです。静的型検査とランタイムバリデーションを同時に実現し、開発者が型安全なアプリケーションを構築できるよう支援します。

mermaidflowchart LR
  schema["Zodスキーマ"] --> parse["parse()"]
  parse --> success["成功: 型付きデータ"]
  parse --> error["失敗: ZodError"]
  schema --> infer["z.infer<>"]
  infer --> types["TypeScript型"]

図解:Zod スキーマから型推論とバリデーションの両方を実現する仕組みを示しています。

TypeScript におけるバリデーションの必要性

TypeScript の静的型検査は、コンパイル時にのみ動作します。外部 API やユーザー入力など、実行時に受け取るデータの型安全性は保証されません。

typescript// コンパイル時は問題なし
interface User {
  name: string;
  age: number;
}

// しかし実行時はunknown
const apiResponse: User = await fetch('/api/user').then(
  (res) => res.json()
);

この課題を解決するために、実行時バリデーションが必要になります。

基本型の重要性

Zod の基本型は、複雑なスキーマ定義の構成要素として機能します。これらをマスターすることで、オブジェクトや配列などの複合型も効率的に扱えるようになります。

mermaidflowchart TD
  basic["基本型<br/>string/number/boolean<br/>date/enum/literal"]
  basic --> object["オブジェクト型"]
  basic --> array["配列型"]
  basic --> union["ユニオン型"]
  object --> complex["複雑なスキーマ"]
  array --> complex
  union --> complex

図解:基本型から複雑なスキーマへの構築プロセスを表しています。

課題

基本型の使い方がわからない

Zod を始めたばかりの開発者にとって、各基本型の定義方法やメソッドチェーンの使い方は混乱しがちです。特に、バリデーションルールの追加方法やエラーメッセージのカスタマイズについて理解が不足しています。

それぞれの型の特徴と使い分けが不明

stringliteralnumberと enum など、似た用途を持つ型の違いや使い分けの基準が明確でないことが多くあります。適切な型選択ができないと、バリデーションの精度が低下します。

実際のコードでの活用方法がわからない

理論的な理解はあっても、実際のプロジェクトでどのように活用すれば良いのか、パフォーマンスやメンテナンス性を考慮した実装方法がわからないという課題があります。

解決策

Zod の基本型一覧

Zod は以下の 6 つの基本型を提供しています。それぞれが特定の JavaScript/TypeScript の型に対応し、独自のバリデーション機能を持ちます。

#基本型対応する JS/TS 型主な用途
1stringstring文字列データの検証
2numbernumber数値データの検証
3booleanboolean真偽値の検証
4dateDate日付・時刻の検証
5enumenum/union選択肢の制限
6literalliteral type特定の値に限定

各型の基本的な使い方

基本的なパターンとして、以下の手順でスキーマを定義し、バリデーションを実行します。

typescriptimport { z } from 'zod';

// 1. スキーマの定義
const schema = z.string();

// 2. バリデーションの実行
const result = schema.parse('Hello World');

型安全性の確保方法

Zod はz.inferを使用して、スキーマから TypeScript 型を自動生成できます。これにより、スキーマと型定義の二重管理を避けられます。

typescriptconst userSchema = z.object({
  name: z.string(),
  age: z.number(),
});

// 型の自動生成
type User = z.infer<typeof userSchema>;
// User = { name: string; age: number; }

具体例

string 型

文字列のバリデーションを行う最も基本的な型です。様々な文字列制約を設定できます。

基本的な使用方法

typescriptimport { z } from 'zod';

// 基本的なstring型
const basicString = z.string();

文字列長の制約

typescript// 最小・最大文字数の指定
const lengthString = z
  .string()
  .min(3, '3文字以上で入力してください')
  .max(50, '50文字以内で入力してください');

パターンマッチング

typescript// 正規表現によるパターンマッチ
const emailString = z
  .string()
  .email('有効なメールアドレスを入力してください');

const urlString = z
  .string()
  .url('有効なURLを入力してください');

// カスタム正規表現
const phoneString = z
  .string()
  .regex(
    /^\d{3}-\d{4}-\d{4}$/,
    '電話番号の形式が正しくありません'
  );

文字列の変換

typescript// 前後の空白削除
const trimmedString = z.string().trim();

// 大文字・小文字変換
const lowerString = z.string().toLowerCase();
const upperString = z.string().toUpperCase();

number 型

数値のバリデーションと変換を行います。整数・浮動小数点の両方に対応しています。

基本的な使用方法

typescript// 基本的なnumber型
const basicNumber = z.number();

// 整数のみ許可
const intNumber = z.number().int('整数を入力してください');

数値範囲の制約

typescript// 最小・最大値の指定
const rangeNumber = z
  .number()
  .min(0, '0以上の値を入力してください')
  .max(100, '100以下の値を入力してください');

// 正の数・負の数
const positiveNumber = z
  .number()
  .positive('正の数を入力してください');
const negativeNumber = z
  .number()
  .negative('負の数を入力してください');

特殊な数値条件

typescript// 有限数のチェック
const finiteNumber = z
  .number()
  .finite('有限数を入力してください');

// 安全な整数範囲
const safeNumber = z
  .number()
  .safe('安全な整数範囲で入力してください');

// 複数条件の組み合わせ
const scoreNumber = z.number().int().min(0).max(100);

boolean 型

真偽値のバリデーションを行います。文字列からの変換機能も提供されています。

基本的な使用方法

typescript// 基本的なboolean型
const basicBoolean = z.boolean();

// 使用例
const isActive = basicBoolean.parse(true); // true
const isInactive = basicBoolean.parse(false); // false

文字列からの変換

typescript// 文字列を真偽値に変換
const coerceBoolean = z.coerce.boolean();

// 使用例
coerceBoolean.parse('true'); // true
coerceBoolean.parse('false'); // false
coerceBoolean.parse('1'); // true
coerceBoolean.parse('0'); // false
coerceBoolean.parse(''); // false

実用的な例

typescript// フォームデータの処理
const settingsSchema = z.object({
  notifications: z.boolean(),
  newsletter: z.coerce.boolean(), // チェックボックスの値を変換
  isPublic: z.boolean().default(false), // デフォルト値
});

date 型

日付・時刻のバリデーションを行います。Date 型への変換機能も含まれています。

基本的な使用方法

typescript// 基本的なdate型
const basicDate = z.date();

// Dateオブジェクトのバリデーション
const now = basicDate.parse(new Date()); // 成功

文字列からの Date 変換

typescript// 文字列をDateに変換
const coerceDate = z.coerce.date();

// 使用例
coerceDate.parse('2024-01-01'); // Date オブジェクト
coerceDate.parse('2024-01-01T10:00:00Z'); // Date オブジェクト
coerceDate.parse(1640995200000); // タイムスタンプから変換

日付範囲の制約

typescript// 最小・最大日付の指定
const futureDate = z
  .date()
  .min(new Date(), '今日以降の日付を選択してください');

const pastDate = z
  .date()
  .max(new Date(), '今日以前の日付を選択してください');

// 範囲指定
const eventDate = z
  .date()
  .min(new Date('2024-01-01'))
  .max(new Date('2024-12-31'));

実用的な例

typescript// イベント登録フォーム
const eventSchema = z
  .object({
    startDate: z.coerce.date(),
    endDate: z.coerce.date(),
  })
  .refine((data) => data.endDate > data.startDate, {
    message: '終了日は開始日より後である必要があります',
    path: ['endDate'],
  });

enum 型

事前定義された選択肢の中から値を選択する際に使用します。TypeScript の enum とネイティブ enum の両方に対応しています。

ネイティブ enum

typescript// 文字列配列からenum作成
const fruitEnum = z.enum(['apple', 'banana', 'orange']);

// 使用例
fruitEnum.parse('apple'); // "apple"
fruitEnum.parse('grape'); // ZodError

TypeScript enum 連携

typescript// TypeScript enumの定義
enum UserRole {
  ADMIN = 'admin',
  USER = 'user',
  GUEST = 'guest',
}

// Zodでのenum使用
const roleEnum = z.nativeEnum(UserRole);

// 使用例
roleEnum.parse(UserRole.ADMIN); // "admin"
roleEnum.parse('admin'); // "admin"

実用的な例

typescript// ユーザー登録フォーム
const userSchema = z.object({
  role: z.enum(['admin', 'user', 'guest']).default('user'),
  status: z.enum(['active', 'inactive', 'pending']),
  priority: z.enum(['low', 'medium', 'high']),
});

// APIレスポンスの型定義
const apiResponseSchema = z.object({
  status: z.enum(['success', 'error', 'loading']),
  data: z.unknown().optional(),
});

literal 型

特定の値のみを許可する厳密な型です。定数値や設定値の検証に使用されます。

基本的な使用方法

typescript// 文字列リテラル
const acceptLiteral = z.literal('accept');
acceptLiteral.parse('accept'); // "accept"
acceptLiteral.parse('reject'); // ZodError

// 数値リテラル
const versionLiteral = z.literal(1);
versionLiteral.parse(1); // 1
versionLiteral.parse(2); // ZodError

// 真偽値リテラル
const trueLiteral = z.literal(true);
trueLiteral.parse(true); // true
trueLiteral.parse(false); // ZodError

複数リテラルの組み合わせ

typescript// ユニオン型での使用
const statusLiteral = z.union([
  z.literal('draft'),
  z.literal('published'),
  z.literal('archived'),
]);

// より簡潔な書き方(enumと同等)
const themeLiteral = z.union([
  z.literal('light'),
  z.literal('dark'),
  z.literal('auto'),
]);

実用的な例

typescript// 設定ファイルのスキーマ
const configSchema = z.object({
  environment: z.union([
    z.literal('development'),
    z.literal('staging'),
    z.literal('production'),
  ]),
  logLevel: z.union([
    z.literal('debug'),
    z.literal('info'),
    z.literal('warn'),
    z.literal('error'),
  ]),
  apiVersion: z.literal('v1'),
});

// フォームの状態管理
const formStateSchema = z.object({
  step: z.union([z.literal(1), z.literal(2), z.literal(3)]),
  isSubmitting: z.literal(false).or(z.literal(true)),
});

まとめ

Zod の 6 つの基本型は、TypeScript での型安全なアプリケーション開発において重要な役割を果たします。各型の特徴を理解し、適切に使い分けることで、堅牢なバリデーション機能を持つアプリケーションを構築できます。

特に重要なポイントは以下の通りです。

  • string 型:文字列制約や変換機能を活用した柔軟なバリデーション
  • number 型:数値範囲や型制約を組み合わせた精密な検証
  • boolean 型:型変換機能を活用したフォームデータの処理
  • date 型:文字列からの変換と日付範囲制約による実用的な日付検証
  • enum 型:選択肢制限による安全な値管理
  • literal 型:厳密な値制限による設定値や定数の管理

これらの基本型をマスターすることで、より複雑なオブジェクト型や配列型のスキーマ定義にも自信を持って取り組めるようになるでしょう。

関連リンク