TypeScriptでフォームバリデーションと型を同期する方法!初心者向け完全ガイド
生徒
「インターネットの画面で、名前やメールアドレスを入力するフォームを作りたいです。でも、間違った文字が入力されたときに自動でチェックして、さらにプログラムの型というものと連動させるにはどうすればいいですか?」
先生
「それはフォームバリデーションと型の同期という仕組みを使います。TypeScriptという言葉を使うと難しく聞こえますが、入力チェックのルールと、プログラムが覚えるデータの形をぴったり一致させる素晴らしい方法があるんですよ。」
生徒
「バリデーションって何ですか?パソコンに慣れていない私でも仕組みが分かりますか?」
先生
「バリデーションとは、入力された内容が正しいかどうかを確かめる確認作業のことです。今回は、パソコンの操作やプログラミングが初めての人でも絶対に理解できるように、基本から分かりやすく丁寧にお話ししていきますね!」
1. フォームバリデーションと型同期の基本を知ろう
ウェブサイトで会員登録をするときに、名前を入力したり、メールアドレスを入力したりする欄のことをフォームと呼びます。このフォームに、おかしなデータが入力されないように監視する仕組みがフォームバリデーションです。
たとえば、メールアドレスの入力欄に文字が何も入っていなかったり、数字しか書かれていなかったりしたら困りますよね。そのような場合に「これは正しい入力ではありませんよ」と教えてあげるのがバリデーション、つまり入力チェックの役割です。
そして、TypeScriptというプログラミング言語には、データの引き出しに名前をつけるような型(かた)という仕組みがあります。入力チェックのルールと、この型のルールがバラバラだと、後からプログラムが混乱してしまいます。これらを全く同じ内容として合体させ、連動させることを型の同期(どうき)と呼びます。
2. なぜ入力チェックと型を一致させることが大切なのか
パソコンのプログラムは、少しでもルールが違うと動かなくなってしまいます。もし、入力画面のチェックルールでは「パスワードは8文字以上」としているのに、プログラムの奥にある型のルールでは「パスワードは何文字でも良い」となっていたらどうなるでしょうか。途中でデータがすれ違ってしまい、エラーという不具合の原因になります。
入力チェックのルールと型のルールを常に同じ状態に同期させておくと、以下のようなたくさんの安心が得られます。
- 入力間違いを画面ですぐに見つけて、利用者に親切に伝えることができる
- プログラムを作る人が、データの形を勘違いして間違えるミスを未然に防げる
- ルールを変更するときに、1箇所だけを書き換えればすべてが自動で切り替わる
このように、安全で使いやすいシステムを作るために、型と入力を一致させることが非常に重要な課題となります。
3. 最初に知っておきたい便利なお助け道具の仕組み
すべてを自分の手だけで書こうとすると、とても難しくて複雑な迷路のようになってしまいます。そこで、世界中のプログラマーが使っている便利なお助け道具を利用します。その代表的な道具がZod(ゾッド)というライブラリです。ライブラリとは、便利な機能があらかじめ詰め込まれた道具箱のことです。
この道具箱を使うと、「この入力欄は文字が入る場所」「この入力欄は必ず入力すること」というルールを、まるで日本語のメモを書くように簡単に決めることができます。そして、その決めたルールから、自動的にTypeScriptの型というものを生み出すことができるのです。これが、今回の目標である同期を実現する鍵になります。
4. 最もシンプルな文字の入力チェックを体験しよう
まずは、一番簡単な例を見てみましょう。ユーザーの名前を受け取るための入力チェックルールを作ります。名前は文字でなければいけませんし、空っぽでは困りますよね。そのようなルールを記述するプログラムです。
// 名前を入力するためのルールを決めます
const nameSchema = zod.string().min(1, "名前は必ず入力してください。");
// 実際に文字が入ってきたと仮定して、ルールに合っているかテストします
const result = nameSchema.safeParse("お名前");
console.log(result.success);
上記のプログラムでは、まず「文字であること」そして「最低でも1文字以上であること」というルールを作っています。もし文字が正しく入っていれば、成功したという結果が返ってきます。このようにして、基本のバリデーションが動きます。実行したときの結果は、画面に以下のように表示されます。
true
この出力結果である「true」とは、プログラミングの世界で「正しい」「成功した」という意味を表す言葉です。もし何も入力されていない場合は、逆の意味の言葉が表示されることになります。
5. 年齢の入力チェックで数字のルールを作ってみよう
次は、数字を入力する場合のルールを考えてみましょう。たとえば、お店の会員登録で年齢を入力してもらう場面です。年齢は数字でなければいけませんし、マイナスの数字や、あまりにも大きすぎる数字はおかしいですよね。今回は「20歳以上であること」というルールを作ってみます。
// 年齢のためのルールを決めます。20歳以上という制限をつけます
const ageSchema = zod.number().min(20, "20歳以上の方のみ登録できます。");
// 18歳という数字を入れて、ルールに合格するか確かめます
const checkAge = ageSchema.safeParse(18);
console.log(checkAge.success);
このプログラムでは、18という数字を入れてテストをしています。私たちが決めたルールは20歳以上ですので、このデータはルール違反ということになりますね。そのため、実行結果は以下のようになります。
false
出力された「false」とは、「間違い」「失敗した」という意味です。プログラムがしっかりと入力内容を見張って、おかしなデータをブロックしてくれたことが分かります。これがバリデーションの心強い仕組みです。
6. 複数の入力欄をまとめた本格的な型同期の方法
実際のインターネットの画面では、名前も年齢もメールアドレスも、たくさんの情報を一度に入力しますよね。それらを一つのグループとしてまとめて、さらに型を自動的に同期させる方法を学びましょう。これが本番でよく使われる強力な書き方です。
// 会員登録フォーム全体のルールを大きな箱として作ります
const registrationSchema = zod.object({
userName: zod.string().min(1, "お名前は必須です"),
userEmail: zod.string().email("正しいメールアドレスの形式で書いてください"),
userAge: zod.number().min(18, "18歳未満は登録できません")
});
// このルールから、自動的にTypeScriptの型を取り出して同期させます
type RegistrationData = zod.infer<typeof registrationSchema>;
ここで注目してほしいのが、一番最後の行です。zod.inferという魔法の言葉を使っています。これは、上で決めた入力チェックのルールをそのまま読み取って、TypeScriptの型というデータ定義に一瞬で変換してくれる機能です。
これによって、入力チェックのルールを変更すれば、自動的にプログラム全体の型も書き換わります。手作業で2箇所を直す必要がなくなるため、間違いが絶対に起きない安全な環境が完成します。
7. 画面に表示するHTMLの部品との連携イメージ
最後に、このプログラミングの仕組みが、実際のウェブ画面のどこに繋がっているのかをイメージしてみましょう。画面を作るためのHTMLという言葉で書かれた部品の例です。以下のような入力欄が用意されます。
<form id="userForm">
<label>お名前の入力欄:</label>
<input type="text" id="userNameInput">
<label>メールアドレスの入力欄:</label>
<input type="email" id="userEmailInput">
<button type="submit">登録する</button>
</form>
この画面のボタンが押された瞬間に、先ほど作ったTypeScriptのチェックルールが動き出します。もしメールアドレスの欄に不備があれば、画面に赤文字で注意書きを出すといった処理を行います。ルールと型が美しく同期しているため、どのようなデータが流れてきても、プログラムは迷うことなく正確に処理を続けることができます。