---
title: "Zodの使い方入門｜npm install zodとz.infer・safeParse【最新4.6.7・脆弱性修正】"
url: "https://www.issoh.co.jp/tech/details/7391/"
published: 2025-06-24
updated: 2026-11-01
categories: ["TypeScript"]
publisher: "株式会社一創"
---

# Zodの使い方入門｜npm install zodとz.infer・safeParse【最新4.6.7・脆弱性修正】

Zod（ゾッド）は、TypeScriptの型とランタイムの入力検証を1つのスキーマで書けるnpmパッケージです。2026年10月25日時点の最新版は**4.6.7**（10月12日公開）で、`npm install zod`の1行で入ります。**4.6.5以前はnpm auditで「high」と表示される脆弱性GHSA-mrhx-c7xc-m3w5の対象**なので、既存のプロジェクトは版の確認から始めてください。この記事では、インストールと安全確認、`z.infer`による型の取り出し、`parse`・`safeParse`・`validate`の使い分け、Zod 3から書き換えが必要なAPIまでを、Node.js 26とTypeScript 7.0.2で実際に動かしたコードで説明します。

## まとめ：Zod 4.6.7で押さえる導入と検証の要点

- **導入**：`npm install zod`（pnpmは`pnpm add zod`、yarnは`yarn add zod`）。外部依存ゼロで型定義も同梱。tsconfig.jsonの`"strict": true`が必須です。
- **版**：4.6.6以上に上げます。4.6.5以前は、上限付きの配列でも、不正な要素を100万個渡すと要素ごとのエラーを組み立て、多量のメモリを消費します（掲載例の計測ではヒープが約320MB増加）。上限の無い配列は4.6.7でも直らないので、`.max()`を他のチェックより前に書きます。
- **型**：`type User = z.infer<typeof User>`でスキーマから型を作ります。`transform`を挟むなら`z.input`と`z.output`を分けます。
- **検証**：想定外の失敗は`parse`（例外）、ユーザー入力は`safeParse`（結果オブジェクト）、真偽だけ欲しいなら`validate`。ただし`validate`は変換後の値を返しません。
- **Zod 3からの書き換え**：`z.string().email()`は`z.email()`へ、`message`は`error`へ、`.merge()`は`.extend()`へ、`error.format()`は`z.treeifyError()`へ。

## Zodの役割とnpmでの採用規模

TypeScriptの型注釈は、コンパイル後の実行時には何も保証しません。`await req.json() as User`と書いても、`age`に文字列が入っていればそのまま通ります。Zodはこの境界で値を検査し、合格した値だけに型を付けます。

npmの週間ダウンロード数は2026年10月16日〜22日で約2.2億回、9月27日〜10月3日は約3.9億回でした（npmのダウンロード統計APIの[10月16日〜22日](https://api.npmjs.org/downloads/point/2026-10-16:2026-10-22/zod)と[9月27日〜10月3日](https://api.npmjs.org/downloads/point/2026-09-27:2026-10-03/zod)の値）。GitHubのcolinhacks/zodはスター数44,191（2026年10月25日取得・MITライセンス）です。tRPCやReact Hook Formのリゾルバなど、多くのライブラリがZodのスキーマをそのまま受け取ります。型安全なAPI層との組み合わせは[tRPCとは？REST・GraphQL・gRPCとの違いと型安全なAPI実装をv11の実コードで解説](/tech/details/7937/)で扱っています。

## npm・pnpm・yarnによるZodのインストール手順

```
npm install zod
pnpm add zod
yarn add zod
```

入る版はnpmの`latest`タグで、2026年10月25日時点は4.6.7です。`npm view zod dist-tags`を叩くと`canary`（4.5.0-canary系）や`beta`（4.1.13-beta.0）も並びますが、どちらも`latest`より古い開発版のタグなので本番では使いません。入っている版は`npm ls zod`で確かめます。他のライブラリが依存として古いZodを抱えている場合も、ここに木構造で出ます。npm自体の仕組みは[npmとは？CLIとレジストリの役割・package.jsonとv12の変更点を解説](/tech/details/17664/)を参照してください。

公式の要件は2つです。TypeScriptはv5.5以降でテストされており、それより古い版は公式サポート外。そしてtsconfig.jsonで`"strict": true`を有効にします。strictに含まれる`strictNullChecks`が無効だと、`nullable`と`optional`の違いが`z.infer`の型に現れません。TypeScript側の設定の基本は[TypeScriptとは？型・型推論・型注釈の書き分けとJavaScriptとの違い【2026年版】](/tech/details/2815/)にまとめています。

読み込みは名前空間インポートが公式の書き方です。

```
import * as z from "zod";

const User = z.object({
  name: z.string().min(1),
  age: z.number().int().nonnegative(),
  email: z.email(),
  tags: z.array(z.string()).max(3),
});
```

`int()`は整数、`nonnegative()`は0以上（`min(0)`と同じ）、`max(3)`は配列の要素数の上限です。オブジェクトは既定で未知のキーを取り除いて通します。未知のキーをエラーにするなら`z.strictObject()`、残して通すなら`z.looseObject()`を使います（Zod 3の`.strict()`・`.passthrough()`は非推奨）。

### TypeScript 7.1でZod 4.6.5以前が出すTS5115

2026年10月20日に公開されたTypeScript 7.1.0-betaでは、Zod 4.6.5以前の型定義が`error TS5115: Instantiations of the following types appear infinitely circular`を出します。手元の再現では、`skipLibCheck`が`false`なら`import`しただけでZod側の`schemas.d.cts`に、`true`でも`z.record(z.string(), z.json())`の行に出ました。TypeScript 7.0.2では出ず、Zod 4.6.7なら7.1.0-betaでも出ません。修正は4.6.6に入った[PR #6645](https://github.com/colinhacks/zod/pull/6645)です。TypeScriptを7.1へ上げる前に、Zodを4.6.6以上にしておきます。

## Zod 4.6.6の脆弱性修正とnpm installの安全確認

4.6.5以前が入ったプロジェクトで`npm audit`を実行すると、次の警告が出ます。

```
# npm audit report

zod  <4.6.6
Severity: high
Zod can exhaust memory while validating oversized constrained collections - https://github.com/advisories/GHSA-mrhx-c7xc-m3w5
```

[GHSA-mrhx-c7xc-m3w5](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5)（CVE-2023-54404）はCVSS 3.1で7.5、対象は4.6.6未満、修正版は4.6.6です。アドバイザリの公開は2026年10月1日、修正版の公開は10月11日でした。`--save-exact`で版を固定していると`npm audit fix`だけでは上がらず、`--force`を求められます。その場合は`npm install zod@latest`で明示的に上げてください。

### 上限付きの配列・Set・Mapで起きていたメモリ枯渇

原因は、`.max()`・`.length()`・`.size()`の判定が全要素の検証後に走っていたことです。上限100を書いていても、各要素が検証に失敗する配列を100万要素渡すと、要素ごとのissueが100万件作られ、上限超過のissueも加わります。4.6.6の[PR #6652](https://github.com/colinhacks/zod/pull/6652)で、上限の判定が要素の検証より前に移りました。次のコードで、4.6.5と4.6.7の違いを確かめられます。

```
import * as z from "zod";

const input = Array(1_000_000).fill(0); // 文字列の配列に数値を100万個
const schemas = {
  max: z.array(z.string()).max(100),
  unbounded: z.array(z.string()),
  refineThenMax: z.array(z.string()).refine(() => true).max(100),
  maxThenRefine: z.array(z.string()).max(100).refine(() => true),
};
for (const [name, s] of Object.entries(schemas)) {
  const t0 = performance.now();
  const r = s.safeParse(input);
  console.log(name, r.error?.issues.length, r.error?.issues[0].code, (performance.now() - t0).toFixed(1));
}
```

ケース間の影響を抑えるため、Node.js 26.5.0の別プロセスで各ケースを1回ずつ計測した参考値です。実行時間とヒープ増分は、実行環境やGCのタイミングによって変動します。

| 書き方                  | 4.6.5のissue数 | 4.6.5の時間 | 4.6.7のissue数 | 4.6.7の時間 |
| -------------------- | ------------ | -------- | ------------ | -------- |
| `.max(100)`          | 1,000,001    | 768ms    | 1（too\_big）  | 1.6ms    |
| `.max(100).refine()` | 1,000,001    | 678ms    | 1（too\_big）  | 1.6ms    |
| `.refine().max(100)` | 1,000,001    | 857ms    | 1,000,001    | 723ms    |
| 上限なし                 | 1,000,000    | 835ms    | 1,000,000    | 648ms    |

issueが100万件規模になったケースは、どれもヒープが約320MB増えました。

### 4.6.7に上げても直らない2つの書き方

表の下2行が、版を上げても残る穴です。PR #6652は対象を「他のどのチェックよりも前にある上限」に限っており、`.refine()`の後ろに書いた`.max()`は従来どおり要素の検証後に判定されます。上限を書いていない配列は、そもそも早く打ち切る根拠がないので変わりません。アドバイザリの説明文は上限の無い配列での攻撃を書いていますが、4.6.6で直ったのは上限付きの側です。同じCVEを扱う[VulnCheckのアドバイザリ](https://www.vulncheck.com/advisories/zod-uncontrolled-resource-consumption-via-array-validation)は対象を「zod <= 4.6.7」とし、上限の無い既定の書き方を直した版はまだ無いと書いています。`npm audit`はGitHubのアドバイザリ（4.6.6未満）を参照するので、4.6.7に上げれば警告は消えますが、上限の無い配列はそのまま残ります。

外部から配列を受け取るスキーマには、`z.array(...).max(n)`を他のチェックより先に書きます。あわせてHTTPの入口でリクエストボディのサイズ上限を設け、検証ライブラリに届く前に量を止めます。

### 9月21日の不正コミットと配布物の確かめ方

4.6.6の[リリースノート](https://github.com/colinhacks/zod/releases/tag/v4.6.6)によると、漏えいしたGitの認証情報で9月21日にmainへ6件の不正コミットが押し込まれ、同日中に[PR #6620](https://github.com/colinhacks/zod/pull/6620)で取り消されました。npmへは1度も公開されていません。海外の一部ニュースは「4.6.6にpreinstallスクリプトが入った」と報じましたが、npmから4.6.5〜4.6.7のtarballを取得して`package.json`を確認すると、`preinstall`・`install`・`postinstall`はどの版にもなく、依存パッケージもゼロでした。4.6.7と4.6.6の差は版番号の文字列だけです。

9月24日の[PR #6622](https://github.com/colinhacks/zod/pull/6622)以降、CIはnpmへ直接公開できなくなりました。新しい版はnpmの承認待ちの列に置かれ、メンテナーが2FAで承認するまでインストールできません。手元で確かめられるのは署名と来歴（provenance）です。

```
npm audit signatures
// 1 package has a verified registry signature
// 1 package has a verified attestation
```

zod 4.6.7の来歴は、colinhacks/zodのmainブランチの`.github/workflows/release.yml`からGitHubホストのランナーでビルドされたことを示します（npmのattestations APIで取得）。来歴は「どこでビルドされたか」の保証で、コードの安全性の保証ではありません。不正コミットがmainに残ったままビルドされても来歴は正しく付きます。依存の更新を自動で取り込む運用なら、公開から数日置いて入れる設定と、[ソフトウェアサプライチェーンセキュリティとは？開発工程に組み込む防御と2026年規制対応の実装判断](/tech/details/16232/)で扱っている確認工程を組み合わせてください。

## z.inferによる型の取り出しとz.input・z.outputの違い

`z.infer`はスキーマから静的な型を取り出す型関数です。上の`User`なら次の1行で型ができ、スキーマを直せば型も追随します。

```
type User = z.infer<typeof User>;
// { name: string; age: number; email: string; tags: string[] }
```

注意が要るのは`.transform()`を挟んだときです。入力と出力の型が変わるため、`z.infer`（＝`z.output`）だけでは足りません。次の例は型の変化を示すためのもので、数値に変換できない文字列はNaNになります。実際の年齢入力では変換後に`.pipe(z.number().int().nonnegative())`などの検証を足します。

```
const Age = z.string().transform((s) => Number(s));
type AgeIn = z.input<typeof Age>;   // string
type AgeOut = z.output<typeof Age>; // number
```

フォームの入力値の型には`z.input`、検証後に処理する側の型には`z.output`を当てます。

## parse・safeParse・validateの使い分け

3つとも同じスキーマで検証しますが、失敗の返し方と戻り値が違います。

| メソッド             | 成功時                       | 失敗時                         | 向く場面          |
| ---------------- | ------------------------- | --------------------------- | ------------- |
| `parse`          | 検証済みの値                    | ZodErrorをthrow              | 設定ファイル・内部データ  |
| `safeParse`      | `{ success: true, data }` | `{ success: false, error }` | フォーム・APIリクエスト |
| `validate`（4.6〜） | `true`                    | `false`                     | 件数の多い振り分け     |

失敗が起こり得る入力には`safeParse`を使い、try/catchなしで`success`で分岐します（trueの枝では`data`に型が付きます）。`parse`は「ここで失敗したらバグ」という場所に置き、例外で処理を止めます。非同期の`refine`を含むスキーマでは、それぞれ`parseAsync`・`safeParseAsync`・`validateAsync`を使います。

### validateが返さない変換後の値と既定値

4.6.0（2026年9月9日）で加わった`validate`は真偽値だけを返し、エラーを組み立てない分だけ失敗時が速くなります。見落としやすいのは、**型ガードが効くのは入力の型に対して**で、**変換後の値や既定値は手元に返ってこない**点です。`transform`のコールバック自体は検証中に1回実行されますが（4.6.7で実測）、その結果で元の変数が置き換わることはありません。

```
const Age = z.string().transform((s) => Number(s));
const raw: unknown = "42";
if (Age.validate(raw)) {
  console.log(typeof raw);
}
// string（numberにはならない）

const Cfg = z.object({ port: z.number().default(3000) });
const c: unknown = {};
console.log(Cfg.validate(c), c, Cfg.parse({}));
// true {} { port: 3000 }
```

`transform`・`default`・`coerce`を含むスキーマは、`validate`ではなく`safeParse`の`data`を使ってください。

### ZodErrorのissuesと表示用の整形

失敗の中身は`error.issues`の配列で、各要素が`code`・`path`・`message`を持ちます。冒頭の`User`に不正な値を渡した結果です。

```
const r = User.safeParse({ name: "", age: -1.5, email: "x", tags: [] });
if (!r.success) {
  console.log(r.error.issues.map((i) => [i.code, i.path]));
  console.log(z.prettifyError(r.error));
}
// [ [ 'too_small', [ 'name' ] ], [ 'invalid_type', [ 'age' ] ], [ 'invalid_format', [ 'email' ] ] ]
// ✖ Too small: expected string to have >=1 characters
//   → at name
// ✖ Invalid input: expected int, received number
//   → at age
// ✖ Invalid email address
//   → at email
```

浅いオブジェクトをフィールド単位で返すなら`z.flattenError()`、入れ子を保って返すなら`z.treeifyError()`、ログやCLIなら`z.prettifyError()`です。Zod 3の`error.format()`・`error.flatten()`は非推奨になりました。1行の文字列にしたい場合は外部パッケージのzod-validation-error（5.0.0、Zod 3.25以降と4系に対応）の`fromError(err).toString()`が使えます。

## optional・nullable・nullish・exactOptionalの違い

「値が無い」の表し方は4通りあり、通す値が違います。

| 書き方                | 推論される型                            | キー欠落 | undefined | null |
| ------------------ | --------------------------------- | ---- | --------- | ---- |
| `.optional()`      | `a?: string \| undefined`         | 通す   | 通す        | 弾く   |
| `.nullable()`      | `b: string \| null`               | 弾く   | 弾く        | 通す   |
| `.nullish()`       | `c?: string \| null \| undefined` | 通す   | 通す        | 通す   |
| `.exactOptional()` | `d?: string`                      | 通す   | 弾く        | 弾く   |

DBのNULL許容カラムをそのまま返すAPIなら`nullable`、未入力をundefinedまたはキー欠落として扱うフォームなら`optional`（空文字列は別途処理）、両方が混ざる外部APIなら`nullish`です。`exactOptional`はPATCHリクエストのように「キーが無い＝変更しない」「`undefined`を明示＝不正」と区別したいときに使います。4.6.7でも、キーを省いた入力は合格し、`undefined`を明示した入力は不合格でした。静的な型でもこの区別を適用するには、tsconfig.jsonで`"exactOptionalPropertyTypes": true`を有効にします。

## refine・superRefineによるカスタム検証とエラー文面の日本語化

型だけで表せない条件は`refine`で足します。複数フィールドにまたがる条件はオブジェクト側に付け、`path`でエラーを出す欄を指定します。

```
const Signup = z
  .object({
    password: z.string().min(8, { error: "8文字以上で入力してください" }),
    confirm: z.string(),
  })
  .refine((v) => v.password === v.confirm, {
    error: "パスワードが一致しません",
    path: ["confirm"],
  });
```

1つの条件で複数のissueを出し分けたいときは`superRefine`を使い、`ctx.addIssue()`を必要な回数呼びます。エラー文面の指定はZod 4で`error`に統一されました。`message`はまだ動きますが非推奨で、Zod 3の`invalid_type_error`・`required_error`・`errorMap`は廃止され、`error`に関数を渡す形に置き換わっています。

既定の英語メッセージは、同梱のロケールで日本語に切り替えられます。

```
import * as z from "zod";
import { ja } from "zod/locales";

z.config(ja());
z.string().safeParse(1).error?.issues[0].message;
// 無効な入力: stringが期待されましたが、数値が入力されました
```

`z.config()`はグローバル設定なので、ユーザーごとに言語が変わるサーバーでは切り替えに使わず、`issue.code`と`issue.path`から自前のi18nキーを組み立てるほうが安全です。

## スキーマの合成：extend・intersection・union・再帰

### merge非推奨とextend・intersectionの違い

Zod 3で使われていた`.merge()`はZod 4で非推奨になり、`A.extend(B.shape)`が推奨形です。`z.intersection(A, B)`でも合成できますが、結果は`ZodObject`ではないため`.pick()`・`.omit()`・`.shape`が使えません（実測で`undefined`）。さらに同じキーの型が食い違うと、どんな値も通らないスキーマができます。

```
const A = z.object({ id: z.number() });
const B = z.object({ name: z.string() });
const AB = A.extend(B.shape);

const X = z.intersection(z.object({ v: z.string() }), z.object({ v: z.number() }));
X.safeParse({ v: "a" }).success;
// false（stringでもnumberでも通らない）
```

オブジェクトの合成は`extend`、`intersection`は`extend`で表せない組み合わせ（オブジェクトと`z.record()`など）に限ります。

### discriminatedUnionと再帰スキーマ

型フィールドで分岐するデータは`z.union()`より`z.discriminatedUnion("type", [...])`が向きます。判別キーを先に見て該当するスキーマだけを検証するため、エラーが「全候補で失敗」ではなく該当候補の中身で返ります。型の考え方は[Discriminated Unionとは？判別可能なユニオン型の書き方とneverでの網羅チェック](/tech/details/6593/)で解説しています。

ツリー構造のような再帰は、Zod 4ではゲッターで書けます。`z.lazy()`も引き続き使えますが、ゲッターなら`z.infer`が型注釈なしで再帰型を推論します。

```
const Category = z.object({
  name: z.string(),
  get children() {
    return z.array(Category);
  },
});
type Category = z.infer<typeof Category>;
```

## Zod 3からZod 4系への書き換え表

Zod 4の安定版は2025年5月19日にzod@3.25.0のサブパス`zod/v4`として公開され、2025年7月のzod@4.0.0でパッケージ本体がZod 4になりました。現在も`zod/v3`から旧APIを読み込めるので、ファイル単位で段階的に移行できます。全項目は[公式の移行ガイド（Migration guide）](https://zod.dev/v4/changelog)にあります。

| Zod 3                         | Zod 4                                | 状態             |
| ----------------------------- | ------------------------------------ | -------------- |
| `z.string().email()`          | `z.email()`                          | 非推奨（次のメジャーで削除） |
| `z.string().uuid()`           | `z.uuid()`／`z.guid()`                | RFC準拠に厳格化      |
| `{ message: "..." }`          | `{ error: "..." }`                   | 非推奨            |
| `invalid_type_error`等         | `error`に関数を渡す                        | 廃止             |
| `A.merge(B)`                  | `A.extend(B.shape)`                  | 非推奨            |
| `.strict()`／`.passthrough()`  | `z.strictObject()`／`z.looseObject()` | 非推奨            |
| `error.format()`／`.flatten()` | `z.treeifyError()`                   | 非推奨            |
| `z.record(値)`                 | `z.record(キー, 値)`                    | 1引数は廃止         |
| `.deepPartial()`              | `z.deepPartial(schema)`（4.5以降）       | 旧メソッドは削除       |

「zod email 非推奨」の警告は1行目で、`z.string().email()`は4.6.7でも動きますが型定義の`@deprecated`でエディタに打ち消し線が出ます。挙動が変わって事故になりやすいのは2つです。`z.uuid()`はRFC 9562/4122に沿ってバリアント桁まで検査し、8-4-4-4-12の形だけ合う文字列を弾きます（実測で`00000000-0000-0000-0000-000000000001`は`z.uuid()`で不合格、`z.guid()`で合格）。`z.record(z.enum(["a", "b"]), ...)`は値スキーマが必須なら列挙した全キーを要求し、一部のキーだけを許すなら`z.partialRecord()`を使います。React Hook Formと組み合わせている場合の移行手順は[ReactのZodフォームバリデーション実装｜React Hook Form連携とZod 4移行の注意点](/tech/details/2371/)にまとめています。

## z.compileとZod Miniの採用条件

4.5で入った`z.compile()`は、スキーマの構造に合わせた検証関数を`new Function`で生成し、有効な入力をその高速経路で通します。npmパッケージに同梱されている[READMEのAOT compilationの節](https://github.com/colinhacks/zod/blob/main/packages/zod/README.md#aot-compilation)では、55スキーマのベンチマークで中央値2.4倍、20キーのオブジェクトやオブジェクトの大きな配列で約9倍、素の`z.string()`では効果なしとされています。倍率はスキーマと計測条件で変わるので、[公式ドキュメント](https://zod.dev/compile)の数値も目安として読みます。効く範囲は限られます。

- **無効な入力はほぼ速くならない**：高速経路で失敗すると通常のパーサーでやり直してエラーを作るためです。失敗の判定を速くしたいなら`validate`と組み合わせます（4.6のリリースノートでは無効な入力に対して`safeParse().success`比で最大35倍）。
- **非同期の`refine`・`transform`を含むとコンパイルされない**：エラーにはならず、元のスキーマがそのまま返ります（4.6.7でも`z.compile(asyncSchema) === asyncSchema`は`true`）。確かめるなら`z.compile(schema, { strict: true })`で`ZodCompileAsyncError`を投げさせます。
- **`new Function`を禁じるCSP環境では外す**：`z.config({ jitless: true })`で`import "zod/compile"`による全体のコンパイルは止まりますが、`z.compile()`を直接呼んだ箇所は自分で外します。

小さなスキーマをリクエストごとに数回検証する程度なら、先に同じデータを何度も検証していないかを見直して境界の1回に減らします。`z.compile()`は、数万件単位のバッチやストリームの検証で詰まる経路にだけ当てます。

バンドルサイズを削る手段は`zod/mini`です。`z.string().check(z.minLength(1))`のように関数を組み合わせて書き、ツリーシェイキングが効きます。公式の計測では`z.boolean().parse(true)`をバンドルした場合、Zod Miniが2.12kB、通常のZodが5.91kB（gzip）です。すでにZodの書き方で大量のスキーマを抱える画面では、書き換えのコストに見合いません。最初から関数型APIで小さく作るなら[Valibotとは？Zodとの違いとpipe構文の使い方をv1系の実コードで解説](/tech/details/7584/)、型構文に近い書き方なら[ArkTypeとは？TypeScript実行時型検証の使い方とZodとの違い](/tech/details/5872/)が比較先です。複数のライブラリのスキーマを共通の型で受け取る仕組みは[Standard Schemaとは？Zod・Valibot・ArkTypeを共通で受け取る仕組みと実装例](/tech/details/11777/)で扱っています。型をコードでなくJSON Schemaとして他言語やOpenAPIと共有したい場合の選択肢は[Ajvとは：JSON SchemaをコンパイルするNode.jsの検証ライブラリの使い方とエラー整形](https://www.issoh.co.jp/tech/details/19150/)にまとめています。

## よくある質問

### Zodのインストールコマンドは？

`npm install zod`、`pnpm add zod`、`yarn add zod`のいずれかです。2026年10月25日時点の最新版は4.6.7で、TypeScript 5.5以降とtsconfig.jsonの`"strict": true`が要件です。

### Zod 4.6.6・4.6.7の修正範囲と、更新後に必要な対策は？

4.6.6以上を使います。4.6.6はGHSA-mrhx-c7xc-m3w5の修正版で、9月21日の不正コミットはnpmに公開されておらず、4.6.6と4.6.7のtarballにはインストール時に動くスクリプトがありません。4.6.7は4.6.6と版番号以外同じ中身です。更新後も、配列の上限を他のチェックより前に指定し、HTTPの入口でリクエストボディのサイズを制限してください。

### Zodの読み方と、何をするライブラリですか？

「ゾッド」と読みます。1つのスキーマからTypeScriptの型（`z.infer`）と実行時の検証（`parse`・`safeParse`）の両方が得られる、JavaScript・TypeScript向けのnpmパッケージです。

### z.inferとは何ですか？

Zodスキーマから静的な型を取り出す型関数です。`type User = z.infer<typeof User>`と書くと、スキーマと同じ構造の型ができます。`transform`を含むスキーマでは出力側の型になるので、入力側が必要なら`z.input`を使います。

### parseとsafeParseはどう使い分けますか？

失敗が想定内のフォームやAPIの入力は`safeParse`で`success`を見て分岐し、失敗したらバグとみなす内部データは`parse`で例外を投げます。真偽値だけでよく、変換後の値を使わない場面に限って`validate`も選べます。

## 関連記事

- [ReactのZodフォームバリデーション実装｜React Hook Form連携とZod 4移行の注意点](/tech/details/2371/)
- [ZodからOpenAPIを生成する方法｜zod-to-openapiとZod 4ネイティブ変換・ライブラリの選び分け](/tech/details/5646/)
- [Valibotとは？Zodとの違いとpipe構文の使い方をv1系の実コードで解説](/tech/details/7584/)
- [Standard Schemaとは？Zod・Valibot・ArkTypeを共通で受け取る仕組みと実装例](/tech/details/11777/)
- [バリデーションとは？入力検証の目的・種類・実装パターンと設計を実装者視点で解説](/tech/details/13486/)

---

出典: [Zodの使い方入門｜npm install zodとz.infer・safeParse【最新4.6.7・脆弱性修正】](<https://www.issoh.co.jp/tech/details/7391/>)（株式会社一創）
