TypeScriptというよりかはJavaScriptの紹介になりますが、値をまとめて扱うコレクションとして有名な配列がTypeScriptにもあります。
型は次の2とおりの表記方法があり、自由に選択できます。
const array1: T[] = [];const array2: Array<T> = [];
1番目の筆記方法を単にarrayと呼び、2番目の筆記方法をgenericと呼びます。差はなく、プロジェクトで統一して使えればいいかと思います。一般的なのはarrayです。本書も基本的にarrayでの記述となっています。 JavaScriptのlinterとして有名なESLintでは、この筆記方法をどちらかに統一することを強制するオプションがあります。
T
は使う時、つまりArrayが定義された時ではなく、使う時に型を決めることができるジェネリクスと呼ばれるものです。本書にも記載がありますのでそちらに詳細は譲りますが、このT
はその配列が要素としてどの型を受けつけるかを示します。
たとえば、以下はT
をnumber
とした例です。
const array1: number[] = [1, 1.5, 2];const array2: Array<number> = [1, 1.5, 2];
型を指定すれば、配列の要素はそれ以外を受け付けなくなります。あらかじめ要素が含まれる状態で初期化した時も、あとから追加する時も型のチェックが働きます。
const array: number[] = [1, 'nu'];// Type 'string' is not assignable to type 'number'.
const array: number[] = [];array.push('nu');// Argument of type '"nu"' is not assignable to parameter of type 'number'.
配列を[]というSyntax sugarで書くことができるのはインスタンスに限ります。スタティックメソッドを呼びたい時はArrayと書かなければいけません。たとえば反復可能であることを示すインターフェースのIterableから配列を作成するArray.from<T>()
は[].from<T>()
と書くことはできず、必ずArray.from<T>()
と書かなければいけません。
配列のn
番目の要素にアクセスするためにはarray[n]
のように筆記します。これは他の言語でも大差ないと思いますがこのときは型のチェックが完全に働かないことに注意してください。
const array: number[] = [0];array[100000].toFixed();
上記例は明らかに100000番目には何も入っていませんが、このコードはTypeScriptはnumber
型を返すものとして扱います。つまり型チェックに引っかからずnumber
型にあるメソッドのtoFixed()
を入力できてしまいます。
TypeScriptでは配列が含まないn
番目へのアクセスがあった時は、例外を投げずにundefined
を返します。上記例は結果として後ろにあるtoFixed()
で実行時エラーを起こします。
つまり、TypeScriptはこのように解釈しています。
const element: T = array[n];
実際に返しうる戻り値の型はこのようになります。
const element: T | undefined = array[n];
このチェックを厳密にして、型安全にするオプションがtsconfig.jsonにあります。こちらについてはtsconfig.json Deep Diveの章をご覧ください。
配列を不特定個数の集合と扱うのではなく、ただの有限個の入れ物として扱いたい時はタプルを使うことができます。