でじぼうです。
Zodを使ったバリデーションで一番よく出てくるのが .object()
でも実際の現場では、それだけでは足りないことが多いです。
この記事では .object() と一緒によく使う構文だけにしぼって、未経験でもわかるように解説します!

この記事は下記の方がおすすめ!
- Zodってなに?
- .object() ってなに?
- よく使われる構文の違いが知りたい
Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち
Zodとは?
Zodは、TypeScriptで「入力ルール(バリデーション)」を簡単に定義できるライブラリです。
- 形式チェック(文字列・数値・メールなど)
- 必須・任意の設定
- 条件付きのチェック
などが、読みやすい構文で書けるのが特徴です。
より詳細は下記のブログをご確認ください。
.object()とは?
フォーム全体の「入力ルール」をまとめて定義できる、Zodの土台です。
const schema = z.object({
  name: z.string(),
  email: z.string().email(),
});コードの意味
- nameは文字列の入力が必要(必須)
- emailはメール形式での入力が必要(必須)
このように、.object() を使うことで複数の入力項目を1つのスキーマとしてまとめることができます。
一緒によく使う構文一覧【目的別】
| 構文 | できること | 使用頻度 | 
|---|---|---|
| .superRefine() | 複数項目をまとめてチェック | ◎ よく使う | 
| .partial()(パーシャル) | 全ての項目を「入力なしでもOK」に | ◎ よく使う | 
| .merge() | スキーマ同士を合体 | ○ 時々使う | 
| .extend() | 既存のスキーマに追加する | ○ 時々使う | 
| .pick() | 一部の項目だけ取り出す | ○ 時々使う | 
| .omit() | 一部の項目を除外する | ○ 時々使う | 
.superRefine()とは?
複数項目を「まとめてチェック」したいときに利用します。
const schema = z.object({
  password: z.string(),
  confirm: z.string(),
}).superRefine((data, ctx) => {
  if (data.password !== data.confirm) {
    ctx.addIssue({
      path: ["confirm"],
      message: "パスワードが一致しません",
      code: z.ZodIssueCode.custom,
    });
  }
});コードの意味
📘 data とは?
- z.object({...})に渡したすべての入力値(name, email など)が入っているオブジェクトのことを指す
- React Hook Form の getValues()と同じ構造
📘 ctx.addIssue() とは?
- 条件に合致した場合に、「この項目にエラーがある」と Zod に伝える関数
- path: ["confirm"]と指定すれば、- confirmにエラーメッセージが表示できる
- code: z.ZodIssueCode.customは「独自ルールによるエラー」であることを示す
📘コード全体の意味
- .superRefine()は、バリデーションの対象全体(objectの中身)にアクセスできる関数
- passwordと- confirmが一致していなければ、- confirm項目にエラーを追加
よくある使い方
- パスワード確認
- 日付の前後関係
- 条件付き入力のバリデーション
.partial()とは?
全部「任意入力」にするときに利用します。
const schema = z.object({
  title: z.string(),
  content: z.string(),
}).partial();コードの意味
- titleも- contentも、未入力でもエラーにならない
よくある使い方
- 入力フォームで、どれか1つだけ更新したいとき(プロフィール編集など)
- 一部だけ更新するような画面で、全項目が必須でないとき
.optional() でも同じ意味になる
下記の記載は、上記の.partial()
const schema = z.object({
  title: z.string().optional(),
  content: z.string().optional(),
});
では .partial() を使うメリットは?
- プロパティがたくさんあるときに 1つずつ .optional()を書かなくて済む
- スキーマを再利用する際に、必須版と任意版を簡単に切り替えられる
✅ .optional() を個別に書いてもOK
✅ .partial() は 全部を一括で optional にしたいときに便利!
.merge()とは?
共通ルールと追加ルールを「合体する」ときに利用します。
const base = z.object({ id: z.string() });
const detail = z.object({ name: z.string() });
const schema = base.merge(detail);コードの意味
- idと- nameの両方を含んだ1つのスキーマを作る
よくある使い方
- IDだけで定義した共通スキーマに、画面ごとの入力項目(詳細)を足したいとき
- 共通部分と画面ごとの違いを分けて管理したいとき(保守性アップ)
.extend()とは?
既存のスキーマに追加するときに利用します。
const user = z.object({ name: z.string() });
const extended = user.extend({ age: z.number() });コードの意味
- userに- ageを追加した新しいスキーマを作る
よくある使い方
- もとのスキーマを壊さずに追加したいとき(再利用性アップ)
- 複数画面で userは共通だが、年齢が必要なのは一部だけ…という場面など
.pick()とは?
必要な項目だけ「取り出す」ときに利用します。
const full = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number(),
});
const nameOnly = full.pick({ name: true });コードの意味
- nameだけを含むスキーマを作る
よくある使い方
- 一覧画面などで、一部の情報だけ使いたいとき
- 画面に表示するフィールドを限定したいとき
.omit()とは?
不要な項目だけ「除外する」ときに利用します。
const full = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number(),
});
const noEmail = full.omit({ email: true });コードの意味
- emailを除外したスキーマを作る
よくある使い方
- セキュリティ上、特定の項目を外したいとき(たとえばパスワードなど)
- APIレスポンスで不要な情報を含めたくないとき
補足:.refine() は .object() の中で「項目ごと」に使う
.refine() は単体の項目に対して使い、複数項目にまたがるときは .superRefine() を使います。
z.object({
  username: z.string().refine(val => val !== "admin", {
    message: "admin は使えません",
  }),
});コードの意味
- usernameが “admin” だったらエラーになる、という1つの項目に対する条件

 
  



コメント