2025年5月にzod v4が公開されました。
zod v4ではv3と比較しいくつかの変更点があります。
具体的な変更点は以下の記事が詳しいです。
さて、zod v4では、ZodError
クラスから入力値を取る方法も変更されています。
ZodError
のデータをもとにエラーメッセージを組み立てることも多いかと思いますので、本記事ではZodError
からデータを取得する方法について解説します。
v3の場合
v3までは、issue.received
から入力値を取得する事ができていました。
import { z } from "zod";
const Schema = z.object({
foo: z.number(),
bar: z.number(),
});
const { success, data, error } = Schema.safeParse(
{ foo: 1, bar: "hoge" },
);
if (!success) {
for (const issue of error.issues) {
console.log("code:", issue.code); //=> invalid_type
console.log("path:", issue.path); //=> [ 'bar' ]
console.log("期待値:", issue.expected); //=> number
console.log("入力値:", issue.received); //=> string (入力した値の型が取れる)
}
}
上の例ですと、期待値はnumber型、実際に入力された値はstring型という情報が取得できます。これを元にエラーメッセージを組み立てる事ができます。
v4の場合
v4からは、issue.input
から入力値を取得します。
ただし、parse時に{ reportInput: true }
を渡す必要があります。
import { z } from "zod/v4";
const Schema = z.object({
foo: z.number(),
bar: z.number(),
});
const { success, data, error } = Schema.safeParse(
{ foo: 1, bar: "hoge" },
{ reportInput: true }, // ここでreportInput: trueを渡さないといけない!
);
if (!success) {
for (const issue of error.issues) {
console.log("code:", issue.code); //=> invalid_type
console.log("path:", issue.path); //=> [ 'bar' ]
console.log("期待値:", issue.expected); // => "number"
console.log("入力値:", issue.input); // => "hoge" (入力した値が取れる)
}
}
zod v4では、このようにreportInput
オプションを指定することでissue.input
から実際に入力された値を取得する事ができます。
エラーメッセージをカスタマイズする際は、これらのデータを元に文字列を組み立てます。
const message = `${issue.expected}型じゃなくて……${issue.input}が来た……ってコト!?`;
以上、zod v4でエラーメッセージをカスタマイズする時の入力値の取り方について解説しました。