TypeScript | 基礎文法:配列・タプル – 配列の型推論

TypeScript
スポンサーリンク

配列の型推論とは何か

TypeScriptは、わざわざ「: string[]」のように型を書かなくても、初期値から配列の型を自動で推論してくれます。
つまり、次のように書いた瞬間に、コンパイラは「これは number の配列だな」「これは string の配列だな」と理解します。

const nums = [1, 2, 3];        // number[] と推論される
const names = ["Taro", "Hanako"]; // string[] と推論される
TypeScript

ここで重要なのは、「配列の中身の型を見て、配列全体の型を決めている」という感覚です。
この“中身からの推論”が、配列の型推論の基本になります。


単一の型だけが入っている配列の推論

すべて number の場合

const scores = [80, 90, 100];
// 型: number[]
TypeScript

要素がすべて number なので、「number の配列」と推論されます。
この時点で、TypeScriptは次のようなチェックをしてくれます。

scores.push(120);   // OK
// scores.push("120"); // エラー: string は入れられない
TypeScript

「最初に入っていたもの」と「その後に入れようとしているもの」が型として一致しているかを、ずっと見てくれます。

すべて string の場合

const messages = ["hello", "bye"];
// 型: string[]
TypeScript

同じく、「string の配列」と推論されます。

messages[0] = "hi";   // OK
// messages[1] = 123; // エラー
TypeScript

「配列の型推論=要素の型を見て決める」というパターンが、ここでは素直に効いています。


複数の型が混ざった配列の推論(ユニオン型になる)

number と string が混ざっている場合

const mixed = [1, "2", 3];
// 型: (number | string)[]
TypeScript

TypeScriptは、「この配列には number も string も入っている」と判断し、
「number または string の配列」として推論します。

mixed.push(4);      // OK
mixed.push("5");    // OK
// mixed.push(true); // エラー: boolean はダメ
TypeScript

ここで大事なのは、「配列の要素型がユニオン型になる」ということです。
「(number | string)[]」という形は、実務でもよく出てきます。

boolean などがさらに混ざるとどうなるか

const values = [1, "2", true];
// 型: (number | string | boolean)[]
TypeScript

単純に「出てきた型を全部足したユニオン」になります。
あまりに何でもかんでも混ぜると、型としても「何でもアリ」に近づいてしまうので、
「この配列は何を入れる場所なのか」を意識して設計した方がいいです。


空配列から始めるときの落とし穴

何も入っていないと、推論できない

const xs = [];
TypeScript

中身がないので、TypeScriptは「要素の型」を推論できません。
設定によっては any[] になったり、エラーになったりします。

any[] になってしまうと、「何でも入る配列」になってしまい、型チェックがほぼ効かなくなります。

let xs = [];
xs.push(1);
xs.push("hello");
// xs は any[] になりがち
TypeScript

これはかなり危険な状態です。

空配列から始めるなら、型を明示する

空配列スタートが必要なときは、必ず型を書いてあげるのがおすすめです。

const xs: number[] = [];
xs.push(1);
// xs.push("hello"); // エラー
TypeScript

「この配列は number の配列だ」と最初に宣言しておけば、
空配列から始めても、以降の操作にちゃんと型チェックが効きます。


const と as const が絡んだときの推論

const だけの場合

const colors = ["red", "green", "blue"];
// 型: string[]
TypeScript

const で宣言していても、配列の中身は「string の配列」として推論されます。
要素は "red""green" というリテラル値ですが、型としては string にまとめられます。

as const を付けた場合(タプル+リテラル型になる)

const colors = ["red", "green", "blue"] as const;
// 型: readonly ["red", "green", "blue"]
TypeScript

as const を付けると、「配列」ではなく「タプル」として推論されます。
要素の型も "red" | "green" | "blue" ではなく、それぞれ "red", "green", "blue" というリテラル型になります。

これは「配列の型推論」というより、「タプル+リテラル型推論」の話になるので、
まずは「as const を付けると、普通の配列推論とは違う世界になる」とだけ覚えておけばOKです。


初心者がまず掴んでおきたい配列の型推論の感覚

配列の型推論で本当に大事なのは、この3つです。

「要素が全部同じ型なら、その型の配列として推論される」
「複数の型が混ざっていれば、ユニオン型の配列として推論される」
「空配列は危険なので、型を明示するか、最初から要素を入れておく」

そしてもうひとつ、実務的に効いてくる感覚としては、
「この配列は何の配列なのか?」を常に言語化してから書く、ということです。

「ユーザーの配列なら User[]」
「ID の配列なら number[] か string[]」
「状態の配列なら Status[]」

その「何の配列か」という意図を、TypeScriptは初期値から推論しようとしてくれます。
推論に任せていいところと、「ここはちゃんと型を書こう」という境界線を、自分の中で少しずつ育てていくと、
配列の型推論は一気に“味方”として感じられるようになります。

タイトルとURLをコピーしました