4. パース実行・エラー整形・レジストリ・JSON Schema・静的型推論

Zod v4 はスキーマ構築機能に加え、関数型およびメソッド型の実行エンジン(parse、safeParse、validate、encode、decode)、11種類の判別可能な共用体型に整理された $ZodIssue と組み込みエラーフォーマッタ(prettifyError、treeifyError、flattenError、formatError)、WeakMap ベースの型安全なメタデータレジストリ($ZodRegistry、globalRegistry)、双方向 JSON Schema 変換(toJSONSchema、fromJSONSchema)、および静的・実行時の入出力スキーマ射影ユーティリティ(z.infer、z.input、z.output)を提供します。

04_parsing_errors_registries_jsonschema_1
Zod v4 のパース実行・エラー整形・メタデータレジストリ・JSON Schema 全体像
Source Code
from drawlib import canvas
from drawlib.diagrams.architecture import ArchitectureDiagram, Node, NodeGroup, PhosphorIcon
from drawlib.styles import Styles

canvas.clear()
canvas.setup(width=188, height=96, dpi=150)

d = ArchitectureDiagram(
    node_style=Styles.Primary,
    node_text_style=Styles.DarkBold.patch(text_size=10.0),
    edge_style=Styles.DarkBold,
    edge_text_style=Styles.Dark.patch(text_size=10.0),
    node_card_style=Styles.Neutral,
    title="Zod v4 パース実行・エラー整形・レジストリ・JSON Schema 構造",
)

# Left Group: Parse & Codec Execution (node width=46 -> center x = 5 + 23 = 28)
exec_grp = d.add(
    NodeGroup(title="1. パース・Codec 実行", padding=5.0),
    xy=(0.0, 0.0),
)
parse_node = exec_grp.add(
    Node("順方向パース・型ガード\nparse / safeParse\nparseAsync / validate", width=46, height=20, icon=PhosphorIcon.PLAY_CIRCLE, icon_size=6.5, card_style=Styles.PrimaryNeutral),
    xy=(28.0, 52.0),
)
codec_exec = exec_grp.add(
    Node("双方向 Codec 実行 API\ndecode / encode\nsafeDecode / safeEncode", width=46, height=20, icon=PhosphorIcon.ARROWS_LEFT_RIGHT, icon_size=6.5, card_style=Styles.Neutral),
    xy=(28.0, 15.0),
)

# Center Group: Core Schema & Error Engine (node width=40 -> center x = 5 + 20 = 25)
core_grp = d.add(
    NodeGroup(title="2. コアスキーマ・$ZodError", padding=5.0),
    xy=(66.0, 0.0),
)
schema_hub = core_grp.add(
    Node("ZodType<O, I>\n_zod.run(payload, ctx)\nz.infer / z.input / z.output", width=40, height=20, icon=PhosphorIcon.CUBE, icon_size=6.5, style=Styles.WhiteBold, card_style=Styles.PrimaryFlat, text_style=Styles.WhiteBold.patch(text_size=10.0)),
    xy=(25.0, 52.0),
)
err_hub = core_grp.add(
    Node("ZodError & フォーマッタ\nprettifyError / treeifyError\nflattenError / formatError", width=40, height=20, icon=PhosphorIcon.WARNING_OCTAGON, icon_size=6.5, style=Styles.WhiteBold, card_style=Styles.AccentFlat, text_style=Styles.WhiteBold.patch(text_size=10.0)),
    xy=(25.0, 15.0),
)

# Right Group: Registries & JSON Schema (node width=46 -> center x = 5 + 23 = 28)
meta_grp = d.add(
    NodeGroup(title="3. レジストリ・JSON Schema", padding=5.0),
    xy=(126.0, 0.0),
)
reg_node = meta_grp.add(
    Node("メタデータレジストリ\n$ZodRegistry<Meta>\nz.globalRegistry / .meta()", width=46, height=20, icon=PhosphorIcon.BOOKMARK_SIMPLE, icon_size=6.5, card_style=Styles.Neutral),
    xy=(28.0, 52.0),
)
json_node = meta_grp.add(
    Node("JSON Schema 相互変換\nz.toJSONSchema(schema)\nz.fromJSONSchema(json)", width=46, height=20, icon=PhosphorIcon.FILE_CODE, icon_size=6.5, card_style=Styles.PrimaryNeutral),
    xy=(28.0, 15.0),
)

# Connections
d.connect(parse_node, schema_hub, padding=1.5)
d.connect(codec_exec, schema_hub, padding=1.5)
d.connect(schema_hub, err_hub, label="issues[]", padding=1.5)
schema_hub.fork([reg_node, json_node], at_x=119.0, padding=1.5)
d.connect(reg_node, json_node, label="metadata", padding=1.5)

d.draw(xy=(94.0, 46.0), align="center")
canvas.save()

functionz.parse / z.safeParse / z.parseAsync / z.safeParseAsync#

Zod v4 はスタンドアロン関数(z.parse(schema, data)、z.safeParse(schema, data)、z.validate(schema, data))とインスタンスメソッド(schema.parse(data)、schema.safeParse(data)、schema.validate(data))の両方を提供します。

パースおよび型ガード実行シグネチャ一覧#

関数 / メソッド 戻り値型 失敗時の例外スロー 説明
z.parse(schema, value, ctx?) / schema.parse(value, ctx?) z.output<typeof schema> あり (ZodError) 順方向で value を同期検証します。スキーマやチェックが Promise を返した場合は $ZodAsyncError をスローします。
z.safeParse(schema, value, ctx?) / schema.safeParse(value, ctx?) SafeParseResult<z.output<typeof schema>> なし(非同期時のみ例外) { success: true, data: O } | { success: false, error: ZodError<I> } を返します。error プロパティは初回アクセス時にのみ Issue を確定・構築する遅延 getter です。
z.parseAsync(schema, value, ctx?) / schema.parseAsync(value, ctx?) Promise<z.output<typeof schema>> あり (ZodError で reject) 非同期リファインメントや変換を await しながら非同期検証を実行します。
z.safeParseAsync(schema, value, ctx?) / schema.safeParseAsync(value, ctx?) / schema.spa(value, ctx?) Promise<SafeParseResult<z.output<typeof schema>>> なし safeParse の非同期版です。.spa は ZodType プロトタイプ上のゼロオーバーヘッドなエイリアスです。
z.validate(schema, value, ctx?) / schema.validate(value, ctx?) value is z.input<typeof schema> (boolean) なし(非同期時のみ例外) 高速な真偽値型ガード(abortEarly: true、出力値構築と ZodError 生成を省略し、コンパイル済みバリデータがある場合はファストパスを使用)。
z.validateAsync(schema, value, ctx?) / schema.validateAsync(value, ctx?) Promise<boolean> なし 非同期の真偽値検証(abortEarly: true)。

ParseContext オプション (ParseContext)#

オプション 型 デフォルト 説明
error $ZodErrorMap undefined スキーマ単位およびグローバルロケール設定よりも優先される呼び出し単位のエラーマップ。
reportInput boolean false true の場合、確定後の各 $ZodIssue に生の input 値を含めます(機密データや巨大オブジェクトの保持を防ぐためデフォルトは false)。
jitless boolean false true の場合、このパース呼び出しにおいて eval / new Function による JIT ファストパスを無効化します。
import * as z from "zod";

const UserSchema = z.object({
  id: z.uuid(),
  email: z.email(),
});

// 1. 判別共用体を返す safeParse
const res = z.safeParse(UserSchema, rawPayload, { reportInput: true });
if (!res.success) {
  console.error(z.prettifyError(res.error));
} else {
  console.log(res.data.email);
}

// 2. z.validate() による高速な TypeScript 型ガード
if (z.validate(UserSchema, rawPayload)) {
  // rawPayload は z.input<typeof UserSchema> に絞り込まれる
  console.log(rawPayload.id);
}

functionz.encode / z.decode / z.safeEncode / z.safeDecode#

parse は常に順方向(Input -> Output)で実行されますが、Codec 実行関数群は順方向の decode(Input -> Output)と逆方向の encode(Output -> Input)を対称的に提供します。

Codec 実行シグネチャ一覧#

関数 / メソッド 入力引数の型 戻り値型 実行方向と動作
z.decode(schema, value, ctx?) / schema.decode(value, ctx?) z.input<T> z.output<T> 順方向(direction: "forward")。引数として unknown ではなく静的に z.input<T> を要求します。
z.encode(schema, value, ctx?) / schema.encode(value, ctx?) z.output<T> z.input<T> 逆方向(direction: "backward")。ZodCodec の逆変換(encode)を実行します。スキーマグラフ内に単方向の ZodTransform、ZodDefault、ZodCatch が含まれる場合は $ZodEncodeError をスローします。
z.safeDecode(schema, value, ctx?) / schema.safeDecode(value, ctx?) z.input<T> SafeParseResult<z.output<T>> 例外をスローしない順方向デコード。
z.safeEncode(schema, value, ctx?) / schema.safeEncode(value, ctx?) z.output<T> SafeParseResult<z.input<T>> 例外をスローしない逆方向エンコード(単方向変換が含まれる場合は $ZodEncodeError をスロー)。
z.decodeAsync / z.encodeAsync / z.safeDecodeAsync / z.safeEncodeAsync z.input<T> / z.output<T> Promise<...> 非同期の decode / encode コールバックを持つコーデック向けの非同期版。

classZodError & $ZodError#

バリデーション失敗時には、ZodError<T>(zod、ネイティブ Error を継承)または $ZodError<T>(zod/v4/core)のインスタンスが生成されます。なお z.safeParse() の失敗戻り値 { success: false, get error() } は遅延 getter を採用しているため、.error を実際に参照しない限り ZodError インスタンス化と Issue 整形コストは発生しません。

ZodError<T> のプロパティ・メソッド一覧#

メンバ 型 提供パッケージ 説明
error.issues $ZodIssue[] zod & zod/v4/core 確定されたバリデーション Issue の配列。
error.message string zod & zod/v4/core error.issues を整形済み JSON 文字列として返す遅延 getter(初回読み取り時に計算・キャッシュ)。
error.name "ZodError" | "$ZodError" zod & zod/v4/core エラークラス識別子(instanceof Error は true)。
error.flatten(mapper?) $ZodFlattenedError<T, U> Classic zod (非推奨) スタンドアロン関数 z.flattenError(error, mapper) の使用を推奨。
error.format(mapper?) $ZodFormattedError<T, U> Classic zod (非推奨) スタンドアロン関数 z.formatError(error, mapper) の使用を推奨。

type$ZodIssue & Issue Subtypes#

Zod v4 は、v3 の冗長な Issue コード(invalid_string、invalid_date、invalid_enum_value、invalid_literal 等)を整理・統合し、issue.code を判別キーとする 11種類の判別可能な共用体型($ZodIssue) に標準化しています。

04_parsing_errors_registries_jsonschema_2
Zod v4 における $ZodIssueBase と 11 種類の $ZodIssue 判別共用体サブタイプ階層
Source Code
from drawlib import canvas
from drawlib.diagrams.class_diagram import ClassDiagram, ClassNode
from drawlib.fonts import FontRoboto, FontSourceCode
from drawlib.styles import Styles

canvas.clear()
canvas.setup(width=188, height=104, dpi=150)

cd = ClassDiagram(
    node_style=Styles.Neutral.patch(text_font=FontSourceCode.ROBOTO_MONO, text_size=9.5),
    header_style=Styles.PrimaryNeutral.patch(text_font=FontRoboto.ROBOTO_BOLD, text_size=10.5),
    edge_style=Styles.DarkBold,
    edge_text_style=Styles.Dark.patch(text_size=9.5),
    title="ZodIssue ($ZodIssueBase) — 11種類の判別共用体サブタイプ階層",
)

# Top Root Interface (ClassNode xy is Center!)
base_issue = cd.add(
    ClassNode("$ZodIssueBase", stereotype="interface", width=62, header_style=Styles.SecondaryNeutral.patch(text_font=FontRoboto.ROBOTO_BOLD, text_size=10.5))
    .add_attribute("code", "$ZodIssueCode", visibility="+")
    .add_attribute("path", "PropertyKey[]", visibility="+")
    .add_attribute("message", "string", visibility="+")
    .add_attribute("input", "unknown | undefined", visibility="+"),
    xy=(94.0, 74.0),
)

# Bottom Row 1: Type, Value & Custom Issues
grp_type = cd.add(
    ClassNode("Type, Value & Custom", width=44, header_style=Styles.PrimaryNeutral)
    .add_attribute("invalid_type", "{ expected }")
    .add_attribute("invalid_value", "{ values: Primitive[] }")
    .add_attribute("custom", "{ params?: Record }"),
    xy=(23.0, 22.0),
)

# Bottom Row 2: Range, Size & Divisibility Issues
grp_bounds = cd.add(
    ClassNode("Range & Divisibility", width=44, header_style=Styles.PrimaryNeutral)
    .add_attribute("too_big", "{ origin, maximum }")
    .add_attribute("too_small", "{ origin, minimum }")
    .add_attribute("not_multiple_of", "{ divisor: number }"),
    xy=(70.0, 22.0),
)

# Bottom Row 3: String Format & Object Key Issues
grp_format = cd.add(
    ClassNode("Format & Object Keys", width=44, header_style=Styles.PrimaryNeutral)
    .add_attribute("invalid_format", "{ format, pattern? }")
    .add_attribute("unrecognized_keys", "{ keys: string[] }"),
    xy=(117.0, 22.0),
)

# Bottom Row 4: Union & Collection Issues
grp_coll = cd.add(
    ClassNode("Union & Collections", width=44, header_style=Styles.PrimaryNeutral)
    .add_attribute("invalid_union", "{ errors, discriminator? }")
    .add_attribute("invalid_key", "{ origin, issues }")
    .add_attribute("invalid_element", "{ origin, key, issues }"),
    xy=(164.0, 22.0),
)

cd.connect(grp_type, base_issue, "inheritance", start_side="top", end_side="bottom")
cd.connect(grp_bounds, base_issue, "inheritance", start_side="top", end_side="bottom")
cd.connect(grp_format, base_issue, "inheritance", start_side="top", end_side="bottom")
cd.connect(grp_coll, base_issue, "inheritance", start_side="top", end_side="bottom")

cd.draw(xy=(94.0, 50.0), align="center")
canvas.save()

$ZodIssue 共用体リファレンス一覧#

issue.code TypeScript インターフェース 固有プロパティ 主な発行元スキーマ / チェック
"invalid_type" $ZodIssueInvalidType expected: $ZodInvalidTypeExpected ("string", "number", "int", "object", クラス名など) すべてのプリミティブ・コンテナ型検査、z.instanceof()、z.nonoptional()
"too_big" $ZodIssueTooBig origin: "number" | "int" | "bigint" | "date" | "string" | "array" | "set" | "file", maximum: number | bigint, inclusive?: boolean, exact?: boolean lt, lte, maxLength, maxSize, length, size
"too_small" $ZodIssueTooSmall origin: ..., minimum: number | bigint, inclusive?: boolean, exact?: boolean gt, gte, minLength, minSize, length, size
"invalid_format" $ZodIssueInvalidStringFormat format: $ZodStringFormats | string, pattern?: string, prefix?: string, suffix?: string, includes?: string, algorithm?: string z.email(), z.uuid(), z.iso.*(), regex, startsWith, endsWith, includes, jwt
"not_multiple_of" $ZodIssueNotMultipleOf divisor: number multipleOf / .step()
"unrecognized_keys" $ZodIssueUnrecognizedKeys keys: string[] z.strictObject()
"invalid_union" $ZodIssueInvalidUnion errors: $ZodIssue[][], discriminator?: string, inclusive?: boolean, matches?: number[] z.union(), z.discriminatedUnion(), z.xor()
"invalid_key" $ZodIssueInvalidKey origin: "map" | "record", issues: $ZodIssue[] z.record(keySchema, ...), z.map(keySchema, ...)
"invalid_element" $ZodIssueInvalidElement origin: "map" | "set", key: unknown, issues: $ZodIssue[] z.map(..., valSchema), z.set(valSchema)
"invalid_value" $ZodIssueInvalidValue values: Primitive[] z.literal(), z.enum(), z.nativeEnum(), z.mime()
"custom" $ZodIssueCustom params?: Record<string, any> .refine(), .superRefine(), z.custom()

functionz.prettifyError / z.treeifyError / z.flattenError / z.formatError#

Zod v4 は、$ZodError(または StandardSchemaV1.FailureResult)を人間が読みやすい文字列や UI 向けの構造化エラーツリーに変換する 4 つのツリーシェイク可能なトップレベル関数を提供します。

エラーフォーマッタ比較表#

関数 シグネチャ 出力データ構造 最適なユースケース
z.prettifyError(error) (error: StandardSchemaV1.FailureResult) => string ✖ <message> と → at <dot.path[0]> からなる複数行テキスト CLI 出力、サーバーログ、テストアサーション、LLM プロンプトへのフィードバック
z.treeifyError(error, mapper?) <T, U = string>(error: $ZodError<T>, mapper?: (iss: $ZodIssue) => U) => $ZodErrorTree<T, U> 再帰的な { errors: U[], properties?: { [K]: Tree }, items?: Tree[] } ネストされたフォーム、複雑な JSON ペイロード(旧 formatError の推奨代替)
z.flattenError(error, mapper?) <T, U = string>(error: $ZodError<T>, mapper?: (iss: $ZodIssue) => U) => $ZodFlattenedError<T, U> { formErrors: U[], fieldErrors: { [P in keyof T]?: U[] } } フラットな 1 階層の HTML フォームや Server Actions
z.formatError(error, mapper?) <T, U = string>(error: $ZodError<T>, mapper?: (iss: $ZodIssue) => U) => $ZodFormattedError<T, U> レガシー形式 { _errors: U[], [key]: { _errors: U[] } } Zod v3 の .format() 利用コードとの後方互換性維持
import * as z from "zod";

const ProfileSchema = z.object({
  username: z.string().min(3),
  tags: z.array(z.string().min(2)),
});

const result = ProfileSchema.safeParse({ username: "ab", tags: ["ok", "x"] });
if (!result.success) {
  // 1. CLI やログ向けの整形文字列
  console.log(z.prettifyError(result.error));
  // ✖ Too small: expected string to have >=3 characters
  //   → at username
  // ✖ Too small: expected string to have >=2 characters
  //   → at tags[1]

  // 2. 型安全なネスト構造エラーツリー
  const tree = z.treeifyError(result.error);
  console.log(tree.properties?.username?.errors); // ["Too small: ..."]
  console.log(tree.properties?.tags?.items?.[1]?.errors); // ["Too small: ..."]
}

functionz.config & z.locales#

ランタイム全体のグローバル動作設定とエラーメッセージの多言語化(i18n)は、z.config(newConfig?)(CJS と ESM 間で単一の設定オブジェクトを共有する globalThis.__zod_globalConfig)および z.locales によって管理されます。

$ZodConfig オプションとエラーマップ優先順位#

プロパティ 型 優先順位 / 効果
customError $ZodErrorMap | undefined 優先度 3(スキーマ定義時の error [1]、パース時の ctx.error [2] に次ぐ優先度)。グローバルカスタムエラーマップ。
localeError $ZodErrorMap | undefined 優先度 4(フォールバック直前の基底優先度)。z.config(z.locales.ja()) や z.locales.en() 等で設定します。
jitless boolean | undefined 厳格な CSP 環境(Cloudflare Workers やブラウザ拡張など)向けに、new Function / eval によるオブジェクト高速パスおよびコンパイルシムをグローバルに無効化します。
memoizer $ZodMemoizer | undefined 循環参照を含むオブジェクト・配列のパースを有効化します(z.config({ memoizer: z.memoizer() }))。Classic のコンテナスキーマでは自動初期化されます。
import * as z from "zod";

// デフォルトのエラーメッセージを日本語ロケールに切り替え
z.config(z.locales.ja());

// 特定の Issue コードのみグローバルに上書きし、それ以外はロケールに委譲
z.config({
  customError: (issue) => {
    if (issue.code === "invalid_type" && issue.input === undefined) {
      return "必須項目が未入力です";
    }
    return undefined; // localeError にフォールバック
  },
});

class$ZodRegistry & z.globalRegistry#

Zod v4 は、WeakMap ベースの $ZodRegistry<Meta, Schema> コンテナによってスキーマメタデータをスキーマ本体から分離します。エントリは WeakMap<Schema, Meta> に保持されるため一時的なスキーマの GC を妨げず、id を持つスキーマは z.toJSONSchema() 実行時に自動的に $defs として抽出されます。

$ZodRegistry API とスキーマヘルパー#

メソッド / 関数 シグネチャ 説明
z.registry<Meta, Schema>() registry<T extends object | undefined = object | undefined, S extends $ZodType = $ZodType>(): $ZodRegistry<T, S> メタデータ型 T および対象スキーマ型 S に制約された新しい型付きレジストリを作成します。
z.globalRegistry $ZodRegistry<GlobalMeta> プロセス全体で共有されるシングルトンレジストリ(globalThis.__zod_globalRegistry)。GlobalMeta({ id?, title?, description?, deprecated?, [k: string]: unknown })を保持します。
reg.add(schema, meta) add<S extends Schema>(schema: S, meta: $replace<Meta, S>): this schema に meta を登録します(schema.register(reg, meta) はメソッドチェーン用のラッパー)。
reg.get(schema) get<S extends Schema>(schema: S): $replace<Meta, S> | undefined schema のメタデータを取得します(クローン元の schema._zod.parent から id 以外のメタデータを自動継承)。
reg.has(schema) / reg.remove(schema) / reg.clear() (schema: Schema) => boolean | this 登録有無の確認、単一スキーマの削除、またはレジストリの全消去を行います。
schema.meta(data?) meta(): GlobalMeta | undefined / meta(data: GlobalMeta): this 引数なしの場合は z.globalRegistry からメタデータを取得し、引数ありの場合はスキーマを複製して z.globalRegistry に登録します。
schema.describe(description) (description: string) => this スキーマを複製し、z.globalRegistry に { description } を登録します。

[!TIP] カスタムレジストリの Meta 型定義内でファントムシンボル z.$output および z.$input を使用すると、各スキーマの静的出力型・入力型に連動したメタデータ型制約を記述できます(例: z.registry<{ examples: z.$output[] }>())。

import * as z from "zod";

// 各スキーマの出力型に静的に連動する examples 配列を持つカスタムレジストリ
const docRegistry = z.registry<{
  id?: string;
  title: string;
  examples: z.$output[];
}>();

const PortSchema = z.int().min(1).max(65535).register(docRegistry, {
  id: "PortNumber",
  title: "TCP/UDP ポート番号",
  examples: [80, 443, 8080], // number[] として静的に型検査される
});

functionz.toJSONSchema & z.fromJSONSchema#

Zod v4 は外部ライブラリ不要で Zod スキーマ / レジストリと JSON Schema(draft-2020-12、draft-07、draft-04、openapi-3.0)の双方向変換をサポートします。

z.toJSONSchema & z.fromJSONSchema シグネチャ一覧#

関数 / メソッド シグネチャ 説明
z.toJSONSchema(schema, params?) / schema.toJSONSchema(params?) (schema: $ZodType, params?: ToJSONSchemaParams) => JSONSchema.BaseSchema 単一の Zod スキーマを JSON Schema に変換します。共有スキーマや再帰参照は $defs(Draft-04/07 では definitions)に抽出されます。
z.toJSONSchema(registry, params?) (registry: $ZodRegistry<{ id?: string }>, params?: RegistryToJSONSchemaParams) => { schemas: Record<string, JSONSchema.BaseSchema> } registry 内の id 付き全スキーマを相互参照付きの JSON Schema マップに一括変換します。
z.fromJSONSchema(jsonSchema, params?) (schema: JSONSchema, params?: { defaultTarget?: JSONSchemaVersion; registry?: $ZodRegistry }) => ZodType JSON Schema オブジェクト(draft-2020-12、draft-7、draft-4、openapi-3.0)を解析し、等価な実行時 ZodType スキーマを構築します。

ToJSONSchemaParams オプション#

オプション 型 デフォルト 説明
target "draft-2020-12" | "draft-07" | "draft-04" | "openapi-3.0" "draft-2020-12" 出力する JSON Schema のターゲット仕様バージョン。
io "output" | "input" "output" パイプ、コーデック、デフォルト値、型強制スキーマにおいて "output" 側と "input" 側のどちらを出力するかを選択します。
metadata $ZodRegistry<Record<string, any>> z.globalRegistry title、description、deprecated、examples の付与および名前付き id 定義の抽出に使用するレジストリ。
unrepresentable "throw" | "any" | UnrepresentableHandler "throw" JSON Schema で表現できない型(z.date()、z.bigint()、z.map()、z.transform() など)に遭遇した際の挙動(例外スロー、{} 出力、またはカスタムハンドラ)。
cycles "ref" | "throw" "ref" 再帰的スキーマを $ref ポインタとして出力("ref")するか、例外をスロー("throw")するか。
reused "inline" | "ref" "inline" 複数箇所で再利用されている非再帰スキーマをインライン展開するか $defs に抽出するか。
override (ctx: { zodSchema, jsonSchema, path }) => void undefined 変換された各 JSON Schema ノードをインプレースでカスタマイズするフック関数。
import * as z from "zod";

const UserSchema = z
  .object({
    id: z.uuid(),
    role: z.enum(["admin", "member"]).default("member"),
  })
  .meta({ id: "User", title: "Platform User" });

// OpenAPI 3.0 形式で入力側スキーマを出力
const openApiInput = z.toJSONSchema(UserSchema, {
  target: "openapi-3.0",
  io: "input",
});

// JSON Schema ドキュメントから実行時 Zod スキーマを再構築
const DynamicValidator = z.fromJSONSchema(openApiInput);

typez.infer / z.input / z.output#

Zod v4 において、z.input と z.output は TypeScript の静的型抽出ヘルパー(z.input<typeof S>、z.output<typeof S>、z.infer<typeof S>)であると同時に、実行時のスキーマ射影関数(z.input(schema)、z.output(schema))としても機能します。

静的型抽出・実行時スキーマ射影リファレンス#

構文 種別 シグネチャ / 定義 説明
z.infer<T> / z.output<T> 静的型 T extends { _zod: { output: any } } ? T["_zod"]["output"] : unknown スキーマ T のパース・デコード後の出力型を抽出します。
z.input<T> 静的型 T extends { _zod: { input: any } } ? T["_zod"]["input"] : unknown schema.parse() や z.decode() が受け入れる入力型を抽出します。
z.input(schema) 実行時関数 <T extends $ZodType>(schema: T) => ZodType<z.input<T>, z.input<T>> schema を走査し、すべての ZodPipe / ZodCodec を入力側(def.in)に置き換え、ZodDefault を ZodOptional に書き換えた新しいスキーマを返します。
z.output(schema) 実行時関数 <T extends $ZodType>(schema: T) => ZodType<z.output<T>, z.output<T>> schema を走査し、すべての ZodPipe / ZodCodec を出力側(def.out、パイプ上のチェックも維持)に置き換え、ZodPrefault を剥がした新しいスキーマを返します。
import * as z from "zod";

const AccountCodec = z.object({
  createdAt: z.codec(z.iso.datetime(), z.date(), {
    decode: (s) => new Date(s),
    encode: (d) => d.toISOString(),
  }),
});

// 1. 静的型の抽出
type AccountWire = z.input<typeof AccountCodec>;   // { createdAt: string }
type AccountDomain = z.infer<typeof AccountCodec>; // { createdAt: Date }

// 2. 実行時スキーマ射影(パイプやコーデックを純粋な入力用・出力用スキーマへ書き換え)
const WireOnlySchema = z.input(AccountCodec);     // { createdAt: string } -> { createdAt: string } を検証
const DomainOnlySchema = z.output(AccountCodec);  // { createdAt: Date }   -> { createdAt: Date } を検証