こんにちは。TypeScriptの深淵を覗き込み、その型システムという強力な相棒を使いこなそうとするあなたへ。
今日は、多くのエンジニアが「Zodのような外部ライブラリを入れないとバリデーションはできない」と思い込んでいる壁を壊しましょう。実は、TypeScriptの型システムには、コンパイル時に「入力値が正しいか」を静的に弾き飛ばす強力なエンジンが備わっています。
「型レベルのバリデーション」をマスターすれば、実行時にエラーを投げる前に、エディタ上でバグを握りつぶせるようになります。さあ、一緒に深掘りしていきましょう。
—
1. なぜ「型」でバリデーションするのか?
多くの開発者は、バリデーションを「実行時のデータチェック」だと考えがちです。しかし、TypeScriptの真髄は「プログラムを動かす前に、不正な状態を排除すること」にあります。
もし、「電話番号はハイフンを含めて12文字でなければならない」というルールを型で表現できれば、間違ったデータを入力した瞬間にエディタが赤線を引いて教えてくれますよね。これこそが、開発効率を爆上げする「型による自己防衛」の極意です。
—
2. テンプレートリテラル型で「文字列の形式」を縛る
まずは最もシンプルで強力な「テンプレートリテラル型」を使って、特定の形式(例:`XXX-XXXX`のような郵便番号風の形式)を強制してみましょう。
// 数字が3桁-4桁であることを型で制約する
type ZipCode = `${number}${number}${number}-${number}${number}${number}${number}`;
const validCode: ZipCode = “123-4567”; // OK
const invalidCode: ZipCode = “12-34567”; // エラー: 型定義と一致しません
なぜこれが強力なのか?
これは単なる文字列のチェックではありません。コンパイラが「この変数には、この構造を持つ文字列しか入れさせない」と強く監視している状態です。実行時のロジックを書く前に、データ構造の設計図を完璧に書き上げる……これがプロのやり方です。
—
3. 「Mapped Types」でオブジェクトの値を制約する
次に、オブジェクトの各フィールドに「値の範囲」や「制約」を設けるテクニックです。ここでは、TypeScriptの `Range` 的な表現を擬似的に作る手法を見てみましょう。
// 0から9までの数値のみを許可する型
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
// 「すべてのプロパティがDigitであること」を強制するバリデーター
type DigitConfig
[K in keyof T]: T[K] extends Digit ? T[K] : never;
};
// 使い方
const config: DigitConfig<{ a: 5; b: 9 }> = { a: 5, b: 9 }; // OK
const errorConfig: DigitConfig<{ a: 10; b: 1 }> = { a: 10, b: 1 }; // エラー: 10はDigitではありません
ここがポイント
`[K in keyof T]` という記法は、オブジェクトのキーを反復処理する「Mapped Types」という機能です。これを使うことで、個別の値一つ一つに対して「お前はルールを守っているか?」と型レベルで厳しく問い詰めることができます。
—
4. 陥りやすい罠:TypeScriptは「実行時」には消える
ここで一つ、非常に重要な注意点があります。
「TypeScriptの型は、コンパイル後にすべて消滅する」
これは、型バリデーションは「開発中のエディタ上」や「ビルド時」には最強ですが、「外部からのAPIリクエスト」や「ユーザー入力」という実行時の動的なデータに対しては無力であることを意味します。
- 型バリデーション(今回解説): 開発者のミスを防ぐ、設計を固める。
- 実行時バリデーション(Zod等): ユーザーが送ってきた「正体不明のデータ」を信頼しない。
この二つは役割が違います。「開発中の設計は型で守り、実行時の入力はZodで守る」。このハイブリッドな考え方こそが、世界最高峰のフロントエンドアーキテクトが辿り着く境地です。
—
5. まとめ:型は「守り」ではなく「攻め」の道具
いかがでしたか?TypeScriptの型システムは、単なる「型合わせ」の道具ではなく、あなたのロジックを確実に正解へと導く「制約の言語」です。
1. テンプレートリテラル型でフォーマットを縛る。
2. Mapped Typesでデータ構造を徹底管理する。
3. 型を「コンパイル時のバリデーター」として捉える。
ここをクリアすれば、あなたの書くコードは驚くほど堅牢になり、デバッグに費やす時間が劇的に減るはずです。TypeScriptの型システムをマスターするということは、コードの「揺らぎ」を排除し、論理的な美しさを追求することに他なりません。
さあ、次のコードを書くときは、型を使って「どんな不正なデータも入り込めない聖域」を設計してみてくださいね。応援しています!