TypeScript リテラル型

リテラル型(Literal Types)は、TypeScript において汎用型ではなく特定の値を表す機能です。

これにより、変数の型を広範な string や number などの型ではなく、具体的な値に制限することができます。

これにより、より精密な型制御が可能になり、コードの型安全性が高まります。


SVG 図解:リテラル型 背景 タイトル リテラル型の例 汎用型 汎用型 var direction: string; 任意の文字列を代入できる "up", "down", "abc"... 矢印 リテラル型 リテラル型 var direction: "up" | "down" | "left" | "right" この4つの値のいずれかしか代入できない 矢印 結果 型安全性 誤った値を代入すると コンパイルエラー! direction = "upup" 下半分:リテラル型の種類 リテラル型の種類 文字列リテラル 文字列リテラル "up" | "down" | "left" 特定の文字列に制限 数値リテラル 数値リテラル 1 | 2 | 3 | 100 | 200 特定の数値に制限 ブールリテラル ブールリテラル true | false true または false テンプレートリテラル テンプレートリテラル `on${string}` 動的生成 矢印マーク

なぜリテラル型が必要なのか

TypeScript では、string や number などのデフォルトの型は広範すぎます。

時には、より精密な型制御が必要です。例えば、変数が特定の値のみを取れるようにする場合です。

リテラル型はまさにこのような問題を解決するために生まれました。

概念の説明:リテラル型は汎用型(string、number)の具体的な値です。例えば"up"であるstringのサブタイプであり、代入できるのは特定の文字列のみです。


文字列リテラル型

文字列リテラル型は、変数の値を特定の文字列に制限します。

これは、変数を特定の固定値のみに制限する必要がある場合に非常に役立ちます。

例

// 文字列リテラル型を定義
// direction は4つの特定の値のいずれかでなければならない
var direction: "up" | "down" | "left" | "right";

// 正しい:リテラル型の値を代入
direction = "up";

// エラー:リストにない値を代入
// direction = "upup"; // コンパイルエラー!

console.log("方向: " + direction);

// 型エイリアスを使って再利用可能なリテラル型を作成
// 状態型を定義:3つの固定値のいずれかでなければならない
type Status = "pending" | "active" | "completed";

// 型エイリアスを使用
var currentStatus: Status = "active";
console.log("状態: " + currentStatus);

実行結果:

方向: up
ステータス: active

適用場面:文字列リテラルは、列挙値、ステータスコード、設定オプションなど、特定の値に制限する必要がある場面でよく使用されます。


数値リテラル型

数値リテラル型は、変数の値を特定の数値に制限します。

これは、特定の数値(ステータスコード、エラーコードなど)を使用する必要がある場合に非常に役立ちます。

例

// 数値リテラル型を定義
// code は3つの特定の値のいずれかでなければならない
var code: 200 | 404 | 500;

// 正しい:200 を代入
code = 200;

// エラー:リストにない値を代入
// code = 301; // コンパイルエラー!

console.log("ステータスコード: " + code);

// 数値リテラルを使って列挙型を模倣
// 1週間の日数を定義
type Weekday = 1 | 2 | 3 | 4 | 5 | 6 | 7;

// 1〜7の間の数値のみ代入できる
var today: Weekday = 1;
console.log("今日は曜日: " + today);

説明:数値リテラルは、特に少数の固定値だけが必要な場合に、単純な列挙型(enum)の代わりとして使用できます。


ブールリテラル型

ブールリテラル型は、変数の値を true または false に制限します。

実際、TypeScript の boolean 型は true | false のエイリアスです。

例

// ブールリテラル型を定義
// isActive は true または false のみ
var isActive: true | false;

// true を代入
isActive = true;

// 実際、boolean は true | false のユニオン型
// したがって、この2つの書き方は等価
var flag: boolean = true;

console.log("アクティブか: " + isActive);

ヒント:boolean 自体で十分な場合もありますが、true と false の型を明確に区別する必要がある場合は、true または false を型として使用できます。


オブジェクトリテラル型

オブジェクトリテラル型はオブジェクトの構造を定義でき、readonly 修飾子を使ってプロパティを読み取り専用にできます。

これは、不変オブジェクトを作成する必要がある場合に非常に役立ちます。

例

// オブジェクトリテラル型を定義
// オブジェクトの構造とプロパティの型を指定
type Point = {
    // 点の x 座標
    x: number;
    // 点の y 座標
    y: number;
};

// オブジェクトリテラル型を使用
var p: Point = { x: 10, y: 20 };
console.log("点: " + JSON.stringify(p));

// 読み取り専用オブジェクト型を定義
// readonly 修飾子を使ってプロパティを読み取り専用にする
type ReadonlyPoint = {
    // 読み取り専用の x 座標
    readonly x: number;
    // 読み取り専用の y 座標
    readonly y: number;
};

// 読み取り専用オブジェクト型を使用
var rp: ReadonlyPoint = { x: 1, y: 2 };

// 読み取り専用プロパティを変更しようとするとエラーになる
// rp.x = 3; // コンパイルエラー:読み取り専用プロパティは変更できません

console.log("読み取り専用点: " + JSON.stringify(rp));

実行結果:

点: {"x":10,"y":20}
只读点: {"x":1,"y":2}

適用場面:読み取り専用オブジェクトは、設定オブジェクトや定数オブジェクトなど、変更されることを望まないデータを定義する際によく使用されます。


リテラル型と型推論

TypeScript は変数の宣言方法に応じて、リテラル型を自動的に推論します。

const で宣言された変数は、広範な型ではなく、具体的なリテラル型として推論されます。

例

// var で宣言して代入
// TypeScript は広範な型として推論する
var name = "Alice";    // 型: string(var は再代入できるため)
var age = 25;          // 型: number
var enabled = true;    // 型: boolean

console.log("名前: " + name + ", 年齢: " + age + ", 有効: " + enabled);

// as const を使って深い読み取り専用リテラルを作成
// 配列は読み取り専用タプルになり、値はリテラル型
var colors = ["red", "green", "blue"] as const;

// colors の型は次のようになる:
// readonly ["red", "green", "blue"]

// 配列要素にアクセス
console.log("色: " + colors[0]);

// 変更しようとするとエラーになる
// colors

説明:as const型を最も具体的なリテラル型として推論し、readonly 修飾子を追加します。


テンプレートリテラル型

テンプレートリテラル型は、JavaScript のテンプレート文字列の構文を使用して新しい型を作成します。

これにより、文字列型を動的に生成できます。

例

// テンプレートリテラル型を使ってイベント名を定義
// `on${string}` は "on" で始まる任意の文字列を表す
type EventName = `on${string}`;

// テンプレートリテラル型を使ってハンドラー名を定義
// Capitalize は文字列の先頭文字を大文字にする
type Handler = `handle${Capitalize<string>}`;

// テンプレートリテラル型を使用
var event: EventName = "onClick";
var handler: Handler = "handleSubmit";

console.log("イベント: " + event);
console.log("ハンドラー: " + handler);

// 错误:不符合模板格式
// var e: EventName = "click"; // コンパイルエラー:"on" で始まっていません

运行结果:

事件: onClick
处理器: handleSubmit

組み込みユーティリティ型:テンプレートリテラル型は、Uppercase、Lowercase、Capitalize、Uncapitalize などの組み込みユーティリティ型と組み合わせて使用できます。


実践応用:Redux Action

リテラル型は実際の開発において広く応用されています。

以下では、リテラル型を使用してReduxスタイルのアクションを実装する方法を示します。

例

// Redux スタイルの Action 型を定義する
// ユニオン型を使用して異なるタイプのActionを定義する
type Action =
    // インクリメントタイプの Action、数値型の payload を含む
    | { type: "increment"; payload: number }
    // デクリメントタイプの Action、数値型の payload を含む
    | { type: "decrement"; payload: number }
    // リセット型の Action、ペイロードなし
    | { type: "reset" };

// action を使用する reducer 関数
function reducer(action: Action): void {
    // TypeScript は action.type の値に基づいて action の具体的な型を自動的に推論します。
    switch (action.type) {
        case "increment":
            // この分岐では、action は { type: "increment"; payload: number } と推論されます。
            console.log("增加: " + action.payload);
            break;
        case "decrement":
            // この分岐では、action は { type: "decrement"; payload: number } と推論されます。
            console.log("减少: " + action.payload);
            break;
        case "reset":
            // この分岐では、action は { type: "reset" } と推論されます。
            console.log("重置");
            break;
    }
}

// 異なるタイプの Action をディスパッチする
reducer({ type: "increment", payload: 5 });
reducer({ type: "reset" });

运行结果:

增加: 5
重置

判別可能なユニオン:このパターンは「判別可能なユニオン」(Discriminated Union)と呼ばれ、TypeScript で複数の関連する型を扱うためのベストプラクティスです。


注意事項

  • 类型收窄:switchやifで判定する際、TypeScriptは自動的にリテラル型を絞り込みます。
  • 类型别名:一般的なリテラル型には、typeエイリアスを使用して別名を作成することをお勧めします。
  • const 推断:constで宣言された変数は自動的にリテラル型として推論されます。
  • as const:深い読み取り専用が必要な場合はas constを使用します。

最佳实践:変数を特定の値のみに制限する必要がある場合は、列挙型ではなくリテラル型を優先的に使用します。


まとめ

リテラル型は、TypeScriptが精密な型制御を実現するための重要な機能です。

  • 文字列リテラル:特定の文字列に制限する、例:"up" | "down"
  • 数値リテラル:特定の数値に制限する、例:1 | 2 | 3
  • ブールリテラル:true または false に制限
  • オブジェクトリテラル:オブジェクト構造を定義する際は、readonlyを使用できます。
  • as const:深い読み取り専用のリテラル型を作成する
  • テンプレートリテラル:テンプレート文字列を使用して型を動的に生成する

进阶:リテラル型と判別可能なユニオン型パターンを組み合わせることで、強力な型安全性を実現できます。

其他扩展