リテラルはJavaScriptのプリミティブである値そのものです。
型として文字列リテラルを使用できます。例えば:
let foo: 'Hello';
ここではfoo
という名前の変数を作成しました。それに代入されるリテラル値は'Hello'
のみを許可します。これは以下のとおりです:
let foo: 'Hello';foo = 'Bar'; // Error: "Bar" is not assignable to type "Hello"
それらは単独ではあまり使い所がありませんが、ユニオン型で結合して、強力な(そして便利な)抽象化を作成することができます。
type CardinalDirection =| "North"| "East"| "South"| "West";function move(distance: number, direction: CardinalDirection) {// ...}move(1,"North"); // Okaymove(1,"Nurth"); // Error!
TypeScriptはboolean
とnumber
リテラル型もサポートしています。
type OneToFive = 1 | 2 | 3 | 4 | 5;type Bools = true | false;
かなり一般的にType string is not assignable to type "foo"
というエラーを受け取ります。次の例はこれを示しています。
function iTakeFoo(foo: 'foo') { }const test = {someProp: 'foo'};iTakeFoo(test.someProp); // Error: Argument of type string is not assignable to parameter of type 'foo'
これは、test
が{someProp: string}
型であると推定されるためです。この問題を解決するには、シンプルな型アサーションを使用して、TypeScriptに以下のようにリテラルを推測させます。
function iTakeFoo(foo: 'foo') { }const test = {someProp: 'foo' as 'foo'};iTakeFoo(test.someProp); // Okay!
あるいは、型アノテーションを使うことで、宣言した時点でTypeScriptが正しい型を推論するのを助けることができます。
function iTakeFoo(foo: 'foo') { }type Test = {someProp: 'foo',}const test: Test = { // Annotate - inferred someProp is always === 'foo'someProp: 'foo'};iTakeFoo(test.someProp); // Okay!
文字列型の有効な使用例は次のとおりです。
TypeScript enumsは数字ベースです。上記のCardinalDirection
の例のようにユニオン型の文字列リテラルを使用して文字列ベースの列挙型を模倣することができます。次の関数を使ってKey:Value
構造体を生成することさえできます:
/** Utility function to create a K:V from a list of strings */function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {return o.reduce((res, key) => {res[key] = key;return res;}, Object.create(null));}
そして、keyof typeof
を使ってリテラル型の合成を生成します。完全な例を次に示します。
/** Utility function to create a K:V from a list of strings */function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {return o.reduce((res, key) => {res[key] = key;return res;}, Object.create(null));}/*** Sample create a string enum*//** Create a K:V */const Direction = strEnum(['North','South','East','West'])/** Create a Type */type Direction = keyof typeof Direction;/*** Sample using a string enum*/let sample: Direction;sample = Direction.North; // Okaysample = 'North'; // Okaysample = 'AnythingElse'; // ERROR!
例えば CodeMirrorエディタにはreadOnly
オプションがあります。これは、boolean
またはリテラル文字列nocursor
(有効値: true、false、"nocursor")です。それは次のように宣言することができます:
readOnly: boolean | 'nocursor';
これは本の後方で説明します。