OpenSource-Hub

zod

ライブラリ

colinhacks/zod

TypeScriptベースのランタイムデータバリデーションライブラリで、静的型推論をサポートしています。

概要

Zod は TypeScript ファーストのスキーマ検証ライブラリで、定義から静的型を自動的に推論できます。簡潔でイミュータブルな API を提供し、強力な型安全性をもって信頼できないデータを解析・検証します。ゼロ依存で JSON Schema をサポートし、Node.js およびモダンなブラウザで利用できます。

README プレビュー

\n  \n  Zod\n  \n    TypeScript-first schema validation with static type inference\n    \n    by @colinhacks\n  \n\n\n\n\n\n\n\n\n\n\n\n\n  Docs\n    •  \n  Discord\n    •  \n  𝕏\n    •  \n  Bluesky\n  \n\n\n\n\n\n### [Read the docs →](https://zod.dev/api)\n\n\n\n\n## What is Zod?\n\nZod is a TypeScript-first validation library. Define a schema and parse some data with it. You'll get back a strongly typed, validated result.\n\n```ts\nimport * as z from "zod";\n\nconst User = z.object({\n  name: z.string(),\n});\n\n// some untrusted data...\nconst input = {\n  /* stuff */\n};\n\n// the parsed result is validated and type safe!\nconst data = User.parse(input);\n\n// so you can use it with confidence :)\nconsole.log(data.name);\n```\n\n\n\n## Features\n\n- Zero external dependencies\n- Works in Node.js and all modern browsers\n- Tiny: `2kb` core bundle (gzipped)\n- Immutable API: methods return a new instance\n- Concise interface\n- Works with TypeScript and plain JS\n- Built-in JSON Schema conversion\n- Extensive ecosystem\n\n\n\n## Installation\n\n```sh\nnpm install zod\n```\n\n\n\n## Basic usage\n\nBefore you can do anything else, you need to define a schema. For the purposes of this guide, we'll use a simple object schema.\n\n```ts\nimport * as z from "zod";\n\nconst Player = z.object({\n  username: z.string(),\n  xp: z.number(),\n});\n```\n\n### Parsing data\n\nGiven any Zod schema, use `.parse` to validate an input. If it's valid, Zod returns a strongly-typed _deep clone_ of the input.\n\n```ts\nPlayer.parse({ username: "billie", xp: 100 });\n// => returns { username: "billie", xp: 100 }\n```\n\n**Note** — If your schema uses certain asynchronous APIs like `async` [refinements](https://zod.dev/api#refinements) or [transforms](https://zod.dev/api#transforms), you'll need to use the `.parseAsync()` method instead.\n\n```ts\nconst schema = z.string().refine(async (val) => val.length  "hello"\n```\n\n### AO

FAQ (5)

トラブル対応
なぜ Zod の safeParse で error.message がバリデーションエラーメッセージではなく JSON オブジェクトを返すのですか?

Zod 4では、1つのZodErrorに複数のエラーが含まれる可能性があるため、error.messageはすべてのバリデーションの問題を含むJSON文字列になります。最初の人間が読める形式のメッセージを取得するには、次のようにします:

const parsedData = signupSchema.safeParse(req.body);

if (!parsedData.success) {
  const message = parsedData.error.issues[0]?.message;
  return errorResponse(res, 400, message);
}

すべてのエラーメッセージを取得するには:

const messages = parsedData.error.issues.map(issue => issue.message);

エラー全体を読みやすいテキストとしてフォーマットするには、次のようにします:

z.prettifyError(parsedData.error);

参照 Issue #6646
トラブル対応
Zod v4 で .refine() の型述語が推論される型を絞り込まなくなった問題を修正するにはどうすればよいですか?

.refine() における型述語のサポートが Zod **v4.2.2** で復元されました(PR #5575)。まずアップグレードしてください:

npm install zod@^4.2.2

既存の v3 のパターンで、再び出力型が絞り込まれるはずです:

const mySchema = z.string().refine(
  (val): val is "specific-value" => checkExternalLogic(val)
);

type MyType = z.infer<typeof mySchema>; // "specific-value"

以前の v4 リリースからアップグレードできない場合は、単純な述語ベースの絞り込みには z.custom<T>() を使用してください:

const mySchema = z.custom<"specific-value">(
  (val) => typeof val === "string" && checkExternalLogic(val),
  { message: "Expected specific-value" }
);

z.custom() はバリデーションの ctx を受け取らないため、複数のカスタマイズされた issue を追加できない点に注意してください。古い v4 バージョンでカスタムエラーレポートを行うには、.check() または .transform() をそれらの context API とともに使用し、出力型を明示的にアサート/絞り込んでください。推奨される解決策は、Zod 4.2.2 以降へアップグレードすることです。

参照 Issue #5528
トラブル対応
ZodとTypeScript 7.1 nightlyで`.catchall(z.json())`を使用した際に発生するTS5115 'infinitely circular'エラーを修正するにはどうすればよいですか?

PR #6645 を含むリリースに Zod をアップグレードしてください(npm install zod@latest または yarn add zod@latest を実行)。このエラーは、TypeScript 7.1 dev ビルドと組み合わせた場合の Zod 4.5.4 および 4.6.5 に影響します。TypeScript 7.0.2 は影響を受けません。すぐにアップグレードできない場合は、TypeScript 7.0.2 のままにするか、v4/core/schemas.d.ts および .d.cts 内の $ZodRecordInternals にパッチを適用して、型引数なしで $ZodTypeInternals を継承し、output と input を直接宣言するようにしてください:

export interface $ZodRecordInternals<
  Key extends $ZodRecordKey = $ZodRecordKey,
  Value extends SomeType = $ZodType,
> extends $ZodTypeInternals {
  def: $ZodRecordDef<Key, Value>;
  isst: errors.$ZodIssueInvalidType | errors.$ZodIssueInvalidKey<Record<PropertyKey, unknown>>;
  optin?: "optional" | undefined;
  optout?: "optional" | undefined;
  output: $InferZodRecordOutput<Key, Value>;
  input: $InferZodRecordInput<Key, Value>;
}

参照 Issue #6637
トラブル対応
なぜ esbuild では `import { z } from 'zod'` が `import * as z` よりも4〜5倍大きくなるのですか?また、Zod v4 のバンドルサイズを小さくするにはどうすればよいですか?

これは Zod v4 に影響します(zod@4.6.4 と esbuild@0.28.2 で再現確認済み)。Zod は名前空間を export { z, z as default } としてエクスポートしています。Rollup と Webpack はこの再エクスポートをツリーシェイクできますが、esbuild は再エクスポートされた名前空間オブジェクトを不透明なものとして扱うため、import { z } from 'zod' とデフォルトインポートの両方で約 736 KB が残ってしまいます。名前空間インポートを直接使用してください:

import * as z from 'zod';
z.object({ x: z.string() });

再現例では、これにより出力が 736 KB から約 165 KB に削減されます。esbuild では次の形式を避けてください:
import { z } from 'zod';
import z from 'zod';

個別の関数インポートもツリーシェイク可能です:
import { object, string } from 'zod';
object({ x: string() });

@tanstack/ai のようなサードパーティの依存関係が内部で import { z } from 'zod' を使用している場合は、patch-package でその依存関係にパッチを適用し(またはフォーク/解決先を維持管理し)、import * as z from 'zod' に変更してください。Rollup を使用する Vite のプロダクションビルドは同様の影響を受けません。この差異は主に、esbuild 直接の使用や Vite の開発サーバーなど、esbuild がバンドルを実行する場合に現れます。結果はメタファイルで確認してください:
npx esbuild app.ts --bundle --platform=node --format=esm --outfile=out.mjs --metafile=meta.json

参照 Issue #6597
トラブル対応
私の網羅的な Zod v4 ビジターが $ZodFunction と $ZodPrefault を見落とすのはなぜですか?

コアのドキュメントでは、ドキュメントに記載された $ZodTypes ユニオンからこれらのメンバーが誤って省略されています。packages/zod/src/v4/core/schemas.ts にある正式な定義には、$ZodFunction と $ZodPrefault の両方が含まれています。網羅的なビジターまたは型レベルのスイッチを更新して $ZodFunction と $ZodPrefault を処理するか、ドキュメントに記載されたユニオンをコピーするのではなく、ソースの $ZodTypes からケースを導出してください。ドキュメントの修正では、packages/docs/content/packages/core.mdx 内の $ZodTypes に両方の型が追加され、継承図に $ZodFunction が追加されています。

参照 Issue #6631