Zod 4、いつの間に完成していたの!?
今月 10 日ごろ、私のアンテナに捕捉されることなく Zod の v4 がリリースされました。この記事では、v4 で追加・変更された内容のうち、私 (🔰) が特に注目した機能をご紹介します!
1.【New!】国際化
v4 から、Zod は日本語を含む複数のロケールに対応したエラーメッセージを提供するようになりました 🎉
import * as z from "zod";
z.config(z.locales.ja());
例えば、以下のような日本語のエラーメッセージが表示できます。ただし残念ながら、型名などは英語のままです。
- 無効なメールアドレス
- 小さすぎる値: arrayは1要素以上である必要があります
- 大きすぎる値: stringは50文字以下である必要があります
Zod にブラウザーの言語設定に応じた設定をする API はありませんが、以下のように工夫することで実現できます。
// ブラウザーの言語設定に基づいてロケールを設定
const locale = navigator.languages
.map((lang) => lang.replaceAll("-", "") as keyof typeof z.locales)
.find((lang) => z.locales[lang]);
z.config(locale && z.locales[locale]() || z.locales.en());
ただし、カスタマイズしたエラー メッセージをロケールごとに用意するための API はありません。現時点では「internationalization (国際化)」というより「localization (地域化)」機能という感じです。
今後の拡張に期待しています。
2.【Changed!】email 仕様の明文化
v4 では z.email() でのバリデーション仕様が明記されました。おおよそ Gmail で使われているものと同じなのだそうです。
ちなみに、メール アドレスにはさまざまな形式があることをご存知でしょうか?
📚 Wikipedia: Valid email addresses
実は私は大文字混じりのアドレスを持っています。メール サーバーは given.family@example.com 宛のものも私に届けてくれるとはいえ、"Given.Family"@example.com のような普通じゃないアドレスもサポートしたい場合には、正規表現を指定できます。
z.email({ pattern: z.regexes.rfc5322Email });
3.【New!】ファイル スキーマ
ファイルを送信する際に、MIME タイプやサイズでバリデーションできるようになりました。
z.file()
.mime(["image/png", "image/jpeg", "image/gif", "image/svg+xml", "image/webp"]) // 画像
.min(1_000_000) // 1 MB 以上
.max(10_000_000) // 10 MB 以下
shadcn/ui + React Hook Form で以下のように使用することができます。(なぜか <Input type="file" {...field} /> ではダメでした。)
<FormField
control={form.control}
name="photo"
render={({ field }) => (
<FormItem>
<FormLabel>Photo</FormLabel>
<FormControl>
<Input
type="file"
onChange={(e) => {
const file = e.target.files?.[0];
field.onChange(file);
if (file) {
field.onBlur();
}
}}
name={field.name}
ref={field.ref}
/>
</FormControl>
<FormDescription>
Upload a photo (1MB - 10MB).
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
サーバー側でバリデーションすると、スマホの回線で巨大ファイルの送信を待ってから「大きすぎます」とエラーが返るという残念なことになりますが、これからはクライアント サイドで簡単に判定できますね。
4.【New!】JSON Schema への変換
Zod のスキーマから JSON Schema を生成できるようになりました。これは以下のような用途で活躍しそうです。
- バックエンドが別言語の場合、共通のスキーマとして利用
- API 仕様の自動生成
- VS Code 上での補完や型チェック
const formJsonSchema = z.toJSONSchema(formSchema);
5.【New!】再帰的な構造のオブジェクト
v4 からは、再帰的な構造のオブジェクトのスキーマも定義可能になりました。
以下に公式の例をご紹介します。
const Category = z.object({
name: z.string(),
get subcategories(){
return z.array(Category)
}
});
type Category = z.infer<typeof Category>;
// { name: string; subcategories: Category[] }
一般的なバリデーション項目にはないと思いますが、独自の UI でツリーを作るとすればクライアント側のバリデーションは不要だと思いますが、バックエンドも TypeScript (Zod) を使う場合に活用できそうでしょうか?
まとめ
今回ご紹介した注目ポイントはこちら 🙌
- 国際化
- email 仕様の明文化
- ファイル スキーマ
- JSON Schema への変換
- 再帰的な構造のオブジェクト
今後は新規に Zod を使う時には v4 を使うことになっていくと思います。
既存の実装で v3 を継続利用していて仕様を確認する場合は、公式サイト左上のメニューで Zod 3 を選ぶのをお忘れなく!
他の方の記事紹介
Zod 4 については、ベータ版の頃から日本語記事が執筆されています。素晴らしい記事なので、ぜひ参考にしてください! (投稿日の昇順のつもりです。)
Discussion