superRefine()と.refine()
superRefine()
と.refine()
は Zodでのカスタムバリデーションを行う際の2つの方法で、それぞれの使いどころが異なります。
機能名 |
用途 |
特徴 |
.refine() |
単一のフィールド(値)に対する追加検証 |
値を見て true/false を返す |
superRefine() |
オブジェクトや複数フィールドを跨ぐ検証に使う |
複雑なロジックや相関チェックが可能 |
.refine()
目的
Zodの組み込みバリデーションでは対応できない独自ルールを追加したい時に使う。
特徴
特徴 |
説明 |
カスタムバリデーション |
独自ルールを追加できる |
真偽値を返す |
true なら OK、false ならエラー |
任意のエラーメッセージ |
message で指定可能 |
パスも指定できる |
path を使えばエラーの表示場所を細かく制御できる |
どんなスキーマにも使える |
string , number , object , array などすべてに使える |
基本構文
z.string().refine(
value => 条件式,
{
message: "エラーメッセージ",
path: ["任意の", "パス"]
}
)
使用例
18歳以上かどうか
const ageSchema = z.number().refine(
(val) => val >= 18,
{ message: "18歳未満は登録できません" }
);
ageSchema.parse(20);
ageSchema.parse(15);
パスワードの複雑さチェック
const passwordSchema = z.string().refine(
val => /[A-Z]/.test(val) && /[0-9]/.test(val),
{ message: 'パスワードには大文字と数字を含めてください' }
);
.superRefine()
目的
通常の .refine() は単一のフィールド(文字列や数値など)に対する簡単な条件チェックに使いますが、superRefine() はそれだけでは実現できない以下のような目的に使われます。
- 複数のフィールドの相関チェック
- 条件付きバリデーション(特定の値があるときのみ他の値を必須にするなど)
- バリデーションエラーを任意のフィールドに追加する(フォームUIのエラーメッセージ表示に便利)
特徴
特徴 |
説明 |
複数フィールドの検証 |
オブジェクトの全データを対象にチェックできる |
柔軟なエラー制御 |
エラーの追加先(path )を自由に指定できる |
複雑なロジックに対応 |
if/else などの条件分岐、ループ、他の処理を含んだ検証が可能 |
非同期バリデーション対応 |
async 関数として定義すれば非同期処理も可能(APIでの重複チェックなど) |
基本構文
z.object({
}).superRefine((data, ctx) => {
if (バリデーション失敗条件) {
ctx.addIssue({
path: ['エラーを出したいフィールド名'],
code: z.ZodIssueCode.custom,
message: 'エラーメッセージ',
});
}
});
使用例
パスワードと確認用パスワードの一致チェック
const schema = z.object({
password: z.string(),
confirmPassword: z.string(),
}).superRefine((data, ctx) => {
if (data.password !== data.confirmPassword) {
ctx.addIssue({
path: ['confirmPassword'],
code: z.ZodIssueCode.custom,
message: 'パスワードが一致しません',
});
}
});
開始日が終了日より前であることを検証
const dateSchema = z.object({
startDate: z.date(),
endDate: z.date(),
}).superRefine((data, ctx) => {
if (data.startDate >= data.endDate) {
ctx.addIssue({
path: ['startDate'],
code: z.ZodIssueCode.custom,
message: '開始日は終了日より前にしてください',
});
}
});
違いまとめ
比較項目 |
.refine() |
superRefine() |
バリデーション対象 |
スキーマ単体の値 |
スキーマ全体(主にオブジェクト) |
フィールド相関チェック |
❌ 不可 |
✅ 複数フィールドをまたいだチェック可能 |
エラー追加の柔軟性 |
❌ 限定的(そのフィールドのみ) |
✅ 任意のフィールド・複数エラーを自由に追加可能 |
使用場面 |
数値の範囲、文字列の形式など簡単な検証 |
日付の前後、confirmPasswordとの一致など |
- data:そのオブジェクトのバリデーション対象となる入力データ
- ctx:エラーを追加するための「文脈オブジェクト」
- ctx.addIssue():任意のフィールドにバリデーションエラーを登録する
使い分け
ユースケース |
推奨メソッド |
メール形式、文字長チェックなど単体 |
.refine() |
パスワードと確認用パスワードの一致 |
superRefine() |
「開始日 < 終了日」などの相関バリデーション |
superRefine() |
値があれば形式チェック、なければOK |
.refine() (または .optional().refine(...) ) |
Discussion