混合JSON配列からZodユニオン型を生成する

異なる形状のオブジェクトを含むJSON配列からZod判別ユニオンと通常のユニオンを作成する方法を学びます。

Arrays

詳細な説明

Zodのユニオン型

JSON配列に異なる形状のオブジェクトが含まれる場合、Zodは各バリアントを正しく検証するためにz.union()z.discriminatedUnion()を提供します。

JSON例

[
  { "type": "text", "content": "Hello world" },
  { "type": "image", "url": "https://cdn.example.com/photo.jpg", "alt": "A photo" },
  { "type": "video", "url": "https://cdn.example.com/clip.mp4", "duration": 120 }
]

判別ユニオンスキーマ

import { z } from "zod";

const textBlockSchema = z.object({
  type: z.literal("text"),
  content: z.string(),
});

const imageBlockSchema = z.object({
  type: z.literal("image"),
  url: z.string(),
  alt: z.string(),
});

const videoBlockSchema = z.object({
  type: z.literal("video"),
  url: z.string(),
  duration: z.number(),
});

const blockSchema = z.discriminatedUnion("type", [
  textBlockSchema,
  imageBlockSchema,
  videoBlockSchema,
]);

type Block = z.infer<typeof blockSchema>;

discriminatedUnion vs union

z.discriminatedUnion()は判別フィールドを使用して正しいスキーマを即座に選択するため、z.union()よりも高速より良いエラーメッセージを生成します。

特徴 z.union() z.discriminatedUnion()
共有キーが必要 いいえ はい
パフォーマンス 各オプションを試行 直接ルックアップ
エラーメッセージ 汎用的 判別子を指摘
最適な用途 プリミティブユニオン オブジェクトバリアント

それぞれの使い分け

  • z.discriminatedUnion() — 共通のタグフィールド(typekindactionなど)を共有するオブジェクト。
  • z.union() — プリミティブ型のユニオンや共有判別子を持たないオブジェクト。

例:シンプルなユニオン

// 判別子のないプリミティブやオブジェクト用
const idSchema = z.union([z.string(), z.number()]);
// 文字列IDまたは数値IDのどちらかを受け入れる

判別ユニオンの使用は、ポリモーフィックなAPIレスポンスを検証するためのZodの最も強力なパターンの一つです。

ユースケース

リッチコンテンツエディタを構築し、APIがヘテロジニアスなブロック(テキスト、画像、動画)の配列を返す際に、各バリアントに対する検証済みの型安全なレンダリングロジックが必要な場合に使用します。

試してみる — JSON to Zod Schema

フルツールを開く