TypeScriptでバリデーションルールを再利用する方法!初心者向けデータ検証の共通化ガイド
生徒
「TypeScriptで入力されたデータが正しいかチェックする処理を作っているのですが、同じようなチェックを何度も書くのが大変です。もっと簡単に使い回す仕組みはありませんか?」
先生
「それには、バリデーションルールを再利用する仕組みを作ると便利ですよ。型安全なデータの検証ルールを共通化すれば、効率的に安全なプログラムが書けます。」
生徒
「型安全や共通化と言われると少し難しそうですが、パソコンをあまり触ったことがない私でも作れますか?」
先生
「大丈夫です!データのチェックを専門に行うスタンプのような部品を作るイメージです。基本から順番に、分かりやすく解説していきますね。」
1. バリデーションとは?仕組みを身近な例で学ぼう
パソコンの操作やインターネットの画面で、会員登録をするときに、メールアドレスやパスワードを入力したことがあるかと思います。そのときに、文字が短すぎたり、必要な文字が入っていなかったりすると、画面に赤い文字でエラーが表示されることがあります。この、入力されたデータが正しいかどうかを確認する作業のことを、プログラミングの世界ではバリデーションまたはデータ検証と呼びます。
バリデーションは、プログラムが予期しない動きをしたり、間違ったデータが保存されたりするのを防ぐために、とても重要な役割を持っています。もしこのチェックがないと、名前を入力する場所に数字が入ってしまったり、何も入力されていない空っぽの状態のまま登録が進んでしまったりして、後から大きなトラブルになってしまいます。それを未然に防ぐための警備員のような仕組みがバリデーションです。
2. なぜバリデーションルールを再利用する必要があるのか
例えば、インターネットのショッピングサイトを作るとします。そこでは、会員登録の画面、商品の購入画面、お届け先の変更画面など、さまざまな場所で「郵便番号」や「電話番号」を入力してもらう必要があります。これらの画面ごとに、毎回同じ「数字が何桁であるか」というチェックのプログラムを一から書くのはとても大変です。
もし、何度も同じチェック処理を書いていると、一箇所だけ書き間違えてしまったり、後からルールを変更したくなったときに全ての場所を修正しなければならなくなったりします。修正漏れがあると、特定の画面だけで不具合が起きてしまう原因になります。そこで、一つの決まった検証ルールをあらかじめ作っておき、それを色々な場所で使い回す仕組み(再利用)が必要になります。これにより、修正するときも一箇所を直すだけで済むようになり、間違いのない安全なプログラムを作ることができます。
3. 最初に知っておきたいTypeScriptの型の基本と役割
今回のプログラムで使うTypeScript(タイプスクリプト)という言葉について説明します。これは、プログラムのデータに「型(かた)」という目印をつけることができる機能です。型とは、そのデータが「文字」なのか「数値」なのかをあらかじめ指定するお約束のようなものです。
プログラミング未経験の方に向けて説明すると、型はお菓子の型抜きのようなものです。星型の穴には星型のお菓子しか通りません。同じように、文字の型と決めた場所には、文字しか入れることができないようにパソコンが厳しくチェックしてくれます。これにより、プログラムを実行する前に間違いを見つけることができるため、安全性が大幅に高まります。今回はこの型を活用しながら、データの値を細かくチェックする関数(命令のまとまり)を作っていきます。
4. 最もシンプルな関数を使ったデータ検証の方法
まずは、一番基本となる文字の長さをチェックするプログラムを書いてみましょう。ここでは、ユーザー名が「3文字以上」であるかどうかを確かめるバリデーションの仕組みを作ります。関数という命令の箱を作り、そこに文字を渡すと、正しいか正しくないかを判定してくれます。
function checkMinimumLength(text: string): boolean {
if (text.length >= 3) {
return true;
}
return false;
}
let result1 = checkMinimumLength("たろう");
console.log(result1);
let result2 = checkMinimumLength("み");
console.log(result2);
このプログラムを実行すると、パソコンの画面には以下のように結果が表示されます。
true
false
上記のコードを解説します。text: stringというのは、この関数には文字を入れてくださいという型を指定しています。booleanというのは、結果として「正しい(true)」か「正しくない(false)」のどちらか二択の答えを返しますという意味です。text.lengthで文字の長さを数えており、3以上であれば成功としています。「たろう」は3文字なので成功になり、「み」は1文字なので失敗になります。これがバリデーションの第一歩です。
5. ルールを自由に組み合わせる再利用の仕組みづくり
先ほどの方法では、3文字という決まった数字しかチェックできませんでした。これでは、別の場所で「5文字以上」や「8文字以上」をチェックしたいときに再利用できません。そこで、チェックしたい条件の数字も外から自由に変えられるように、検証ルール自体を新しく作り出す仕組みを考えてみましょう。プログラミングでは、関数の中に関数を入れることで、このような高度な使い回しができるようになります。
function createLengthChecker(requiredLength: number) {
return function(text: string): boolean {
return text.length >= requiredLength;
};
}
let isMinLength5 = createLengthChecker(5);
console.log(isMinLength5("あいうえお"));
console.log(isMinLength5("abc"));
このプログラムを実行すると、以下のような結果が出力されます。
true
false
この仕組みは、検証ルールの工場のようなものです。createLengthChecker(5)を実行すると、「5文字以上かどうかをチェックする専用のスタンプ」が作られます。そのスタンプに「あいうえお」を渡すと5文字なので成功になり、「abc」を渡すと3文字なので失敗になります。これを使えば、括弧の中の数字を変えるだけで、何文字のチェックでも何回でも新しいルールを作り出して再利用することができます。
6. 複数の入力項目をまとめてチェックする実践的な方法
実際のホームページでは、名前だけでなく、年齢やメールアドレスなど複数の項目を同時にチェックすることがほとんどです。これらを一つにまとめて、使いやすい構造に組み立てていきましょう。今回は、名前と年齢のデータを想定して、それぞれのルールがすべて合格しているかを一気に確認するプログラムを作ります。
type UserData = {
name: string;
age: number;
};
function validateUser(data: UserData): boolean {
let isNameValid = data.name.length > 0;
let isAgeValid = data.age >= 20;
if (isNameValid && isAgeValid) {
return true;
}
return false;
}
let userA = { name: "山田太郎", age: 25 };
console.log(validateUser(userA));
let userB = { name: "", age: 18 };
console.log(validateUser(userB));
このプログラムを実行すると、以下のような結果が出力されます。
true
false
新しく出てきたtype UserDataというのは、データの設計図です。このデータには「文字の名前」と「数値の年齢」が必ず入っていますというお約束です。validateUserという関数の中で、名前が空っぽでないかというチェックと、年齢が20歳以上であるかというチェックを同時に行っています。&&というのは「かつ」という意味で、両方の条件が成功したときだけ全体を成功にします。ユーザーAは両方満たしているので成功になり、ユーザーBは名前が空で年齢も満たしていないので失敗になります。
7. 安全性と保守性を高めるためのデータ検証の心構え
バリデーションの仕組みを綺麗に再利用できるようになると、プログラムの見た目がすっきりするだけでなく、間違いが起きにくくなります。プログラミングの世界では、同じコードを何度も書かないという大切なルールがあります。これを意識するだけで、誰が見ても分かりやすく、後からの変更にも強い最高品質のプログラムに仕上げることができます。
特に初心者のうちは、動くものを書くだけで精一杯になりがちですが、今回のように「この処理は他の場所でも使えないかな」と少しだけ立ち止まって考えてみることが大切です。ルールを部品のように小分けにして管理しておくことで、インターネット上の複雑なシステムも、小さな部品の組み合わせで簡単に作ることができるようになります。一歩ずつ仕組みを理解していきましょう。