TypeScriptでZodやYupを使ったバリデーションエラーと例外処理を徹底解説
生徒
「TypeScriptを使ってWebサイトを作っているのですが、ユーザーが入力したデータが正しいかチェックするバリデーションという機能でエラーが出たとき、どう扱えばいいか分かりません。」
先生
「バリデーションエラーの処理は、安全なプログラムを作るためにとても重要です。ZodやYupのような便利なツールを使って、エラーをスマートに扱う方法を学んでいきましょう。」
生徒
「はい!具体的にTypeScriptでどうやってエラーをキャッチして、ユーザーに知らせればいいのでしょうか?」
先生
「例外処理の考え方と、型安全にエラー情報を取得する方法を順番に説明しますね。」
1. バリデーションと例外処理の基本
まずは言葉の意味を整理しましょう。バリデーションとは、日本語で検証という意味です。例えば、お問い合わせフォームでメールアドレスの形式が正しいか、パスワードが短すぎないかなどをチェックする作業を指します。TypeScriptで開発する際、もし入力値が正しくない場合にプログラムが突然停止してしまわないように、例外処理という仕組みでエラーを管理します。
例外処理とは、エラーが起きたときにプログラムを強制終了させず、別の安全な道へ案内してあげるための仕組みです。これを適切に行うことで、ユーザーが間違った情報を送っても、サイトがフリーズすることなく、正しいエラーメッセージを表示できるようになります。
2. Zodによるバリデーションの仕組み
ZodはTypeScriptのための強力なバリデーションライブラリです。ライブラリとは、他の誰かが作ってくれた便利な部品集のことです。Zodを使うと、入力データがどのような形式であるべきかを簡単に定義できます。例えば、ユーザー名が文字列であることや、年齢が18歳以上であることなどを短いコードで書けます。
Zodの素晴らしい点は、TypeScriptの型と自動的に連携することです。これにより、バリデーションが成功したときだけ正しいデータとして扱い、失敗したときだけエラー情報を取得するという安全な設計が可能になります。
import { z } from "zod";
const UserSchema = z.object({
username: z.string().min(3),
age: z.number().min(18),
});
3. try-catch文を使った例外処理
次に、プログラムの中でエラーが起きたときに備えるtry-catch文について解説します。これは、tryブロックの中でエラーが起きる可能性のある処理を行い、もしエラーが発生したら即座にcatchブロックへ移動して、エラー内容に応じた処理を行うものです。
バリデーションを行う際、このtry-catch文を組み合わせることで、エラーが出てもアプリケーション全体が壊れないように守ることができます。プログラムが予測不能な事態に陥ったときでも、catchブロックがしっかりと橋渡しをしてくれるのです。
try {
const result = UserSchema.parse({ username: "A", age: 15 });
} catch (error) {
if (error instanceof z.ZodError) {
console.log("入力内容に誤りがあります:", error.errors);
}
}
4. 型安全なエラーの取得方法
TypeScriptの大きな特徴である「型安全」をバリデーションでも活かしましょう。型安全とは、プログラムを書いている最中に型の不一致などを教えてくれる機能です。Zodのエラーには、どの項目で、どんな理由で失敗したかが詳細に含まれています。
TypeScriptでは、エラーオブジェクトが何者であるかを明確にする必要があります。例えば、それが本当にZodのエラーなのか、それとも別の原因によるエラーなのかをチェックする手順を挟むことで、安全にエラー詳細を取り出し、ユーザーへわかりやすく伝えることができるようになります。
5. Yupとの比較と使い分け
YupもZodと同様に有名なバリデーションライブラリです。機能としてはZodと似ていますが、TypeScriptとの相性という点では、最近はZodがより好まれる傾向にあります。ZodはTypeScriptで作られているため、型定義を自分で書く必要がほとんどないという利点があります。
もし既存のプロジェクトがYupで構築されている場合は、そのままでも問題ありませんが、新しく開発を始めるならZodを検討することをお勧めします。どちらのツールを使うにしても、エラーの内容を型定義に含めるという考え方は変わりません。
import * as yup from "yup";
const schema = yup.object({
email: yup.string().email().required(),
});
async function validateInput(data: unknown) {
try {
await schema.validate(data);
} catch (err) {
console.log("Yupのバリデーションエラー:", err);
}
}
6. 実務で役立つエラー表示のコツ
実際にWebサイトを作るときは、エラーをコンソールに表示するだけでなく、画面上にメッセージを出す必要があります。その際、バリデーションエラーを一つずつ取り出し、どの項目が間違っているかを明示しましょう。
例えば、名前の入力欄には「3文字以上で入力してください」、年齢の入力欄には「18歳以上を選択してください」といった具体的な案内を出します。これにより、ユーザーは迷うことなく入力を修正でき、Webサイトの使い心地が格段に良くなります。TypeScriptとライブラリを上手に使い、エラーさえもユーザー体験を向上させる要素に変えていきましょう。
// エラーの内容を整形して返す関数
function formatErrors(zodError: z.ZodError) {
return zodError.issues.map((issue) => ({
path: issue.path[0],
message: issue.message,
}));
}