TypeScriptで定数とユニオン型を組み合わせてデータバリデーション(入力チェック)を実装する方法を徹底解説!
生徒
「TypeScriptで、決まった文字だけを許可するような入力チェックを作りたいのですが、どのように書けば安全ですか?」
先生
「TypeScriptでは、定数とユニオン型という仕組みを組み合わせることで、指定した値以外を強力に弾くデータバリデーションを簡単に作ることができますよ。」
生徒
「定数やユニオン型を組み合わせると、どのようなメリットがあるのですか?」
先生
「それでは、初心者の方にも分かりやすいように、基本的な使い方からデータバリデーションの仕組みまで詳しく見ていきましょう!」
1. データバリデーションとは?
データバリデーションとは、プログラムに入力されるデータが、あらかじめ決められたルールに沿っているかどうかを確認する仕組みのことです。日本語では入力チェックや妥当性確認とも呼ばれます。
例えば、スマートフォンのアプリで会員登録をするときに、メールアドレスの欄に文字が何も入っていなかったり、数字しか入力されていなかったりしたら困りますよね。また、アンケートの選択肢で「会員」「非会員」のどちらかを選んでほしいのに、「宇宙人」という関係のない文字が入力されてしまうと、その後の処理でエラーが発生してしまいます。
このようなおかしなデータがプログラムの内部に入り込まないように、入り口で厳しくチェックして通せんぼをする役割がデータバリデーションです。正しいデータだけを受け入れることで、ウェブサイトやアプリが誤作動を起こすのを防ぎ、安全に動かすことができるようになります。
2. 定数とは何かを学ぼう
プログラミングの世界における定数(ていすう)とは、一度決めたら後から絶対に中身を変更することができないデータの入れ物のことです。パソコンの画面で例えるなら、鍵がかかった頑丈な箱のようなものです。中に書類を入れたら、後から書き換えたり、別の書類に入れ替えたりすることはできません。
TypeScriptで定数を作るときは、constという命令を使います。これは英語の「constant(不変の、一定の)」という単語が由来になっています。これに対して、後から中身を自由に変えられる箱は「変数(へんすう)」と呼び、letという命令を使って区別します。
データバリデーションを行うときには、チェックの基準となるルールを定数として用意することが基本です。ルールが途中で勝手に変わってしまっては、正しいチェックができなくなってしまうからです。絶対に変わらない基準を作るために、まずは定数という仕組みが必要になります。
3. ユニオン型とは何かを学ぼう
TypeScriptには、型(かた)という重要な概念があります。型とは、データの種類を指定するためのラベルのようなものです。例えば「これは文字です」「これは数字です」というルールをあらかじめ決めておくことで、パソコンがデータを正しく処理できるようになります。
そして、今回の大切なキーワードであるユニオン型(Union Type)とは、複数の型や特定の値を「または」という関係で結びつける仕組みのことです。日本語では共用体型とも呼ばれます。記号の縦棒|を使って表現します。これはパソコンのキーボードで、シフトキーを押しながら円マークのキーを押すと入力できる記号です。
例えば、「会員」または「非会員」のどちらかの文字だけを許可したい場合、このユニオン型を使います。パソコンに対して「この箱には、会員という文字か、非会員という文字のどちらかしか入れてはいけません」という非常に強い約束事をさせることができるのです。この仕組みを使うことで、想定外の変な文字が紛れ込むのを未然に防ぐことができます。
4. 定数とユニオン型を組み合わせるメリット
定数とユニオン型を別々に使うだけでも便利ですが、これらを組み合わせることで、非常に強力で安全なデータバリデーションの仕組みを作ることができます。これをプログラミングの専門用語では「型安全(かたあんぜん)」が高まると表現します。
定数によって「チェックに使う正しい値のリスト」を明確に用意し、ユニオン型によって「そのリストにある文字以外は絶対に受け付けない」という壁を作ります。これにより、開発者がプログラムを書いている途中で、文字の打ち間違え(タイポ)をしただけでも、パソコンがすぐに「その文字は使えませんよ」と赤線を出して教えてくれるようになります。
ウェブサイトを実際に動かす前の、プログラムを書いている段階で間違いに気づけるため、大きな失敗を未然に防ぐことができます。未経験の方でも、この組み合わせを覚えることで、プロが書くような高品質で壊れにくいプログラムを組み立てることができるようになります。
5. 基本的な組み合わせのコードを書いてみよう
それでは、実際にTypeScriptのコードを見てみましょう。ここでは、ユーザーの権限として「管理者(Admin)」と「一般ユーザー(User)」の2つの文字だけを許可する仕組みを作ります。それ以外の文字が入ってきたら、エラーとして処理する簡単なプログラムです。
// 1. 許可する文字のユニオン型を定義します
type UserRole = "Admin" | "User";
// 2. 入力されたデータをチェックする関数(命令のまとまり)を作ります
function checkRole(input: string): void {
if (input === "Admin" || input === "User") {
console.log("正しい権限です。アクセスを許可します。");
} else {
console.log("エラー:不正な権限が指定されました。");
}
}
// 3. 実際に動かして試してみます
const testData1 = "Admin";
checkRole(testData1);
const testData2 = "Guest";
checkRole(testData2);
上記のプログラムを実行すると、パソコンの画面には以下のような結果が表示されます。
正しい権限です。アクセスを許可します。
エラー:不正な権限が指定されました。
このコードでは、UserRoleという名前のユニオン型を作り、2つの文字だけを指定しています。関数の中にあるif文という仕組みを使って、入力された文字が正しいかどうかを順番に確認しています。指定外の文字である「Guest」が渡されたときは、しっかりとエラーの処理に進んでいることがわかります。
6. 配列定数を使った高度なチェック方法
先ほどの書き方でも動きますが、許可したい文字が10個や20個に増えた場合、if文の中に「または、または」と何度も書き続けるのは大変ですし、コードが見づらくなってしまいます。そこで、許可する文字を配列(リスト)の定数としてまとめて管理する方法がよく使われます。
配列を作る際は、最後にas constという特別な命令を付け足します。これを付けることで、パソコンに対して「このリストの中身は絶対に書き換えない不変の定数です」と強く覚えさせることができます。この定数のリストから、自動的にユニオン型を作り出すのがプロのテクニックです。
// 1. 許可する文字列のリストを定数として用意します
const ALLOWED_COLORS = ["Red", "Green", "Blue"] as const;
// 2. 定数のリストから自動的にユニオン型を作ります
type Color = typeof ALLOWED_COLORS[number];
// 3. リストの中に指定の文字が含まれているかチェックする関数です
function validateColor(input: string): void {
// includesという命令を使って、配列の中に文字があるか探します
const isValid = ALLOWED_COLORS.includes(input as any);
if (isValid) {
console.log("利用可能な色です。処理を継続します。");
} else {
console.log("エラー:指定された色は存在しません。");
}
}
// 4. 実験してみます
validateColor("Green");
validateColor("Yellow");
上記のプログラムを実行したときの出力結果は以下のようになります。
利用可能な色です。処理を継続します。
エラー:指定された色は存在しません。
この方法を使うと、許可したい色が増えた場合でも、一番上のALLOWED_COLORSのリストに新しい色を追加するだけで、自動的にユニオン型も更新されます。プログラムを修正する箇所が1箇所で済むため、書き換えの手間が減り、ミスも起きにくくなるという大きなメリットがあります。
7. 実践的なフォーム入力のデータバリデーション
最後に、実際のウェブサイトでお問い合わせフォームや登録画面を作るときに使える、より実践的なデータバリデーションの例を紹介します。今回は、スマートフォンの購入画面などをイメージして、選択されたプラン(料金体制)が正しいかどうかをチェックするプログラムを組み立ててみましょう。
// 1. 利用可能な料金プランの定数リストを定義します
const VALID_PLANS = ["Light", "Standard", "Premium"] as const;
type Plan = typeof VALID_PLANS[number];
// 2. チェック結果を分かりやすく返すための仕組みを作ります
function checkRegistrationPlan(userPlan: string): void {
console.log("入力されたプラン: " + userPlan + " を検証中...");
// リストに含まれているか判定します
if (VALID_PLANS.includes(userPlan as any)) {
console.log("チェック完了:正しいプランです。手続きを進めます。");
} else {
console.log("チェック完了:無効なプラン名が検出されました。");
}
}
// 3. さまざまなデータを入れてテストを行います
const registration1 = "Standard";
checkRegistrationPlan(registration1);
const registration2 = "FreePlan";
checkRegistrationPlan(registration2);
プログラムを実行すると、パソコンの画面には以下のように詳細な検証結果が映し出されます。
入力されたプラン: Standard を検証中...
チェック完了:正しいプランです。手続きを進めます。
入力されたプラン: FreePlan を検証中...
チェック完了:無効なプラン名が検出されました。
このように、定数とユニオン型、そして配列のチェック機能をスマートに組み合わせることで、未経験の方でも簡単かつ確実に、不具合のない安全な入力チェックの仕組みを構築することができます。データの安全性を守るための第一歩として、この実装パターンをぜひ活用してみてください。