TypeScriptではプリミティブ型の中の一部だけを示すような型の表現も可能です。
決め打った値を示す型です。例を見ることが何よりもわかりやすいので以下をご覧ください。
const impossible: false = false;const three: 3 = 3;const radetzky: 'Radetzky' = 'Radetzky';
本来ならboolean, number, string
と型を書くべきところにも値が入っているように見えるこれがリテラル型です。
リテラル型はlet
で宣言してもその値しか代入できません。代入できるのも同じリテラルだけです。
let impossible: false = false;impossible = false;impossible = true;// Type 'true' is not assignable to type 'false'.
これでは定数のconst
と宣言していることと何が違うのかと疑問を持たれる方もいらっしゃるかと思います。const
はESMAScriptで定められている定数の宣言であるのに対し、リテラル型はTypeScriptで用意されたその1値のみを許容する変数あるいは定数のことです。
TypeScriptによる型のサポートはあくまでもコーディング中の話であり、実際に動作する時は型のないJavaScriptになります。他の値が代入できないという制限はもはやなくなっている状態であり、これは上書きできないということが撤廃されていることを意味します。そのためリテラル型をあたかも定数のように使うことは避けてください。
let impossible: false = false;// ...// Type assertionimpossible = true as false;
リテラル型はのちに紹介されるユニオン型との相性がよく併用されます。ここではユニオン型とは|
で区切られた型のどれかであるとだけ解釈してください。
let persons: 1 | 2 | 3 | 4 | 5 = 4;
変数persons
は1
から5
までの値が格納できる変数ということを意味しています。もちろんそれ以外の値は代入できません。
let persons: 1 | 2 | 3 | 4 | 5 = 6;// Type '6' is not assignable to type '1 | 2 | 3 | 4 | 5'.
これはデータ型が異なるリテラル型同士でも可能です。
let age: 'thirty five' | 35 = 35;
また、プリミティブ型、クラスのインスタンスを含むオブジェクト型ともユニオン型を構成することができます。
const response: Response | null = ajax.get('https://....');
意図しない関数、メソッドの戻り値のときにnull
を返す例は(この戻り値が好ましいかは置いておくとして)このようになります。
リテラル型はそのリテラルが所属するデータ型の派生型として解釈されます。この使い方はジェネリクスで頻出します。初めはプリミティブ型の派生型とは一体何かと面食らうことがあるかもしれません。
number
型のNaN, Infinity, -Infinity
はリテラル型として使うことができません。
let inf: Infinity = Infinity;// 'Infinity' refers to a value, but is being used as a type here. Did you mean 'typeof Infinity'?let minInf: -Infinity = -Infinity;// Type expected.let nan: NaN = NaN;// 'NaN' refers to a value, but is being used as a type here. Did you mean 'typeof NaN'?