TypeScriptのリテラル型と型制約の使い方を完全解説!初心者でもわかる型のしばり方
生徒
「TypeScriptで値を決めうちしたいときって、どうすればいいですか?」
先生
「その場合は、リテラル型を使うと便利ですよ。特定の値だけを許可する仕組みです。」
生徒
「型って数字とか文字だけじゃないんですね!」
先生
「そうなんです。リテラル型を使うと、より厳密な型制約ができるので、間違いを減らせます。実際に見てみましょう!」
1. リテラル型とは?
TypeScript(タイプスクリプト)のリテラル型とは、「特定の値だけを許可する型」のことです。
例えば、変数に「赤」「青」「緑」のどれかだけを入れたいときに、リテラル型を使います。
リテラルとは、「文字通りの値」という意味で、リテラル型はその値しか使えないように制限(制約)をかける型のことです。
以下のコードを見てみましょう。
let color: "赤" | "青" | "緑";
color = "青"; // OK
color = "黄色"; // エラー
このように、「赤」「青」「緑」の3つ以外を代入しようとすると、TypeScriptが教えてくれます。
2. ユニオン型と組み合わせて使う
リテラル型は、ユニオン型(複数の型を|でつなぐ書き方)とセットで使うことが多いです。
これにより、許可された複数の値だけを使うようにできます。たとえば、以下のように使います。
type Size = "S" | "M" | "L" | "XL";
let tshirtSize: Size;
tshirtSize = "M"; // OK
tshirtSize = "XXL"; // エラー
typeキーワードで「Size」という型を定義して、使い回すこともできます。
3. 数値のリテラル型も使える
リテラル型は、文字列だけでなく数値にも使えます。
例えば、「1」「2」「3」だけを許可したいときも、次のように書けます。
let rating: 1 | 2 | 3 | 4 | 5;
rating = 4; // OK
rating = 6; // エラー
このように、正確に入力してほしい数だけを許可できるので、バグを防ぐことにもつながります。
4. 関数の引数にリテラル型を使って制約する
リテラル型は、関数の引数に使うことで、「この値しか渡さないで!」と厳しくチェックすることができます。
例えば、以下のようにします。
function setMode(mode: "light" | "dark") {
console.log("現在のモードは:", mode);
}
setMode("light"); // OK
setMode("blue"); // エラー
これにより、setMode関数には「light」か「dark」以外は渡せないようにできます。
間違ったモードを指定しても、TypeScriptがすぐに教えてくれるので安心です。
5. リテラル型と型エイリアスの使い分け
リテラル型は、そのまま使うこともできますが、型エイリアスとして名前をつけておくと、コードが読みやすくなります。
型エイリアスとは、typeというキーワードを使って、型に名前をつけることです。
type Direction = "上" | "下" | "左" | "右";
function move(dir: Direction) {
console.log("キャラクターが" + dir + "に動きました");
}
move("上"); // OK
move("中央"); // エラー
このようにしておくと、何のための型なのかが明確になります。
6. 実行結果の確認
実際にリテラル型を使った関数を実行すると、次のようになります。
現在のモードは: light
キャラクターが上に動きました
リテラル型のおかげで、想定外の入力を防ぎながら、正しい値だけで動かすことができます。
7. なぜリテラル型を使うのか?
リテラル型を使うと、以下のようなメリットがあります:
- ミスを防げる:誤った値を入れるとエラーになるので、間違いにすぐ気づける
- コードが読みやすくなる:許される値が明確なので、他の人が見ても理解しやすい
- 自動補完が効く:開発ツールで候補が出るので、入力ミスも減る
特に、選択肢が限られているデータ(色、サイズ、モードなど)では、積極的にリテラル型を使うのがおすすめです。
まとめ
ここまでリテラル型や型制約について見てきましたが、改めて振り返ってみると、TypeScriptという言語が持つ「値を絞り込む力」がとても大きな意味を持っていることがよく分かります。とくにリテラル型は、プログラムに渡された値が意図しないものだった場合に、すぐに間違いを見つけてくれる心強い仕組みです。選択肢が少ないデータ、たとえば色名やサイズ、モードの切り替えなど、ユーザーが選ぶパターンが限られている場面では、リテラル型を使うことでコードの安定性が高まります。これは初心者にとっても扱いやすく、複雑なルールよりもまず「決まった値だけを許可する」という単純な考えで使えるのが大きな魅力です。 また、ユニオン型との組み合わせは、複数の候補から値を選ばせるような処理と相性が良く、条件分岐が多い場面でも非常に読みやすいコードが書けます。実際にアプリケーション開発では、ユーザー入力や設定の切り替えには決まった選択肢で動く場面が多いため、リテラル型とユニオン型をセットで使うことで、間違いを防ぎつつ保守しやすいコードへと育てていくことができます。 さらに、型エイリアスとして名前をつけておくと、型そのものに「何を表すのか」という意味が宿り、後から見返したときに混乱することがありません。単に「文字列」ではなく、「上・下・左・右のどれか」を表す値や、「S・M・L」の中から選ぶサイズといった役割がはっきりするため、ほかの人と共同で開発する場合にもとても助かります。 以下には、今回学んだリテラル型を使った少し発展的なサンプルを用意しています。実際に複数の選択肢を扱う場面では、このような書き方が効果的に働きます。
追加のサンプルプログラム
次のコードは、ユーザーが選ぶ「テーマカラー」をリテラル型で制限し、その値に応じてメッセージを切り替える例です。許可された色以外は渡せないため、意図しないテーマで画面が崩れる心配もありません。
type ThemeColor = "赤" | "青" | "緑" | "白" | "黒";
function applyTheme(color: ThemeColor): string {
switch (color) {
case "赤":
return "画面テーマを赤に変更しました。";
case "青":
return "画面テーマを青に変更しました。";
case "緑":
return "画面テーマを緑に変更しました。";
case "白":
return "画面テーマを白に変更しました。";
case "黒":
return "画面テーマを黒に変更しました。";
}
}
console.log(applyTheme("赤"));
console.log(applyTheme("黒"));
このサンプルのように、特定の選択肢だけを使う場面ではリテラル型が非常に便利です。switch分岐と組み合わせることで、「この値のときはこの処理」という対応関係がひと目で分かり、間違いのない実装につながります。加えて、エディタが自動で候補を出してくれるため、タイプミスを防ぐ効果もあります。 また、設定画面や入力フォームなどでも、限られた選択肢に合わせてリテラル型を設けることで、ユーザーの操作意図とプログラムの動作が一致しやすくなります。特にUI操作の多いフロントエンドでは、リテラル型による型制約が安全性と読みやすさの両方に貢献します。 数値のリテラル型も同様に便利で、段階評価や一定数から選ぶ入力値などに適用できます。こうして「値の範囲を意図的に狭める」ことで、プログラム全体が想定外の動作をしなくなり、品質の高いコードへと近づいていきます。小さな制約の積み重ねが、最終的には大きな信頼性につながるのです。
生徒
「先生、リテラル型って最初は地味だと思っていたんですけど、実際に使ってみると便利ですね!」
先生
「そうなんだよ。値を決めうちできるだけで、プログラム全体の安全性がぐっと上がるんだ。特に選択肢が限られているデータでは効果が大きいね。」
生徒
「ユニオン型と組み合わせると、より実用的になっていくのも分かりました。サイズとかモードの設定とか、実際のアプリでも使われてそうですね。」
先生
「まさにその通り。リテラル型は現場でとてもよく使われるから、今のうちにしっかり身につけておくと、どんなコードでも読みやすく書けるようになるよ。」
生徒
「型エイリアスも覚えておくと便利ですね。名前をつけるだけで、型の意味がはっきりして安心感があります。」
先生
「うん、名前を付けるとコードに意図が宿るんだ。今回学んだリテラル型は、TypeScriptの型の中でも特に使いどころが多いから、ぜひ色んな形で試してみてね。」