TypeScript | 基礎文法:配列・タプル – union型配列

TypeScript
スポンサーリンク

union型配列とは何か(まずイメージから)

union型配列は、「この配列には“いくつかの型のどれか”が入る」ということを型で表現したものです。
たとえば「number か string のどちらかが入る配列」は、こう書きます。

const values: (number | string)[] = [1, "2", 3, "4"];
TypeScript

(number | string)[] は「number または string の配列」という意味です。
要素ごとに number だったり string だったりしてもよくて、とにかく「この2種類以外は入れない」という約束を型で表現しています。


union型配列の基本形と読み方

(A | B)[] という形に慣れる

union型配列の基本形は、(A | B)[] です。
かっこの中が「要素として許される型の選択肢」、その後ろの [] が「その配列」という意味になります。

type Id = number | string;

const ids: Id[] = [1, 2, "3", "4"];
TypeScript

この場合、ids は「number か string のどちらかである Id 型の配列」です。
Id[](number | string)[] と同じ意味になります。

ここで大事なのは、「配列の中に“混ざっていてもいい”」ということです。
1番目が number、2番目が string、3番目が number…のように、順番もバラバラで構いません。


union型配列でできること・できないこと

許される値と弾かれる値

type Value = number | string;

const values: Value[] = [1, "2", 3];

values.push(4);      // OK(number)
values.push("5");    // OK(string)
// values.push(true); // エラー(boolean は Value ではない)
TypeScript

Valuenumber | string なので、そのどちらかなら配列に追加できます。
逆に、boolean のように union に含まれていない型は、コンパイル時に弾かれます。

「何でもアリ」ではなく、「この中のどれかだけアリ」というのが union型配列の重要なポイントです。

取り出したときの型に注意する

const v = values[0];
// v の型: number | string
TypeScript

取り出した要素の型は number | string になります。
つまり、「どちらか分からない」状態なので、そのままでは数値メソッドも文字列メソッドも安全に呼べません。

// v.toFixed(2);      // エラー(string かもしれない)
// v.toUpperCase();   // エラー(number かもしれない)
TypeScript

ここで必要になるのが「型ガード」です。

if (typeof v === "number") {
  console.log(v.toFixed(2));   // ここでは number として扱える
} else {
  console.log(v.toUpperCase()); // ここでは string として扱える
}
TypeScript

union型配列は、「入れるときは柔軟」「使うときはちゃんと確認してから」というスタイルになります。


(A | B)[] と A[] | B[] の違いは超重要

「要素が混ざる」のか「配列の種類が2パターンある」のか

よく混同されるのが、次の2つです。

let a: (number | string)[];
let b: number[] | string[];
TypeScript

(number | string)[] は、「1つの配列の中に number と string が混ざっていてもいい」型です。
一方 number[] | string[] は、「この変数には number の配列か string の配列のどちらかが入る」という意味で、
1つの配列の中で混ざることは想定していません。

a = [1, "2", 3];      // OK
// b = [1, "2", 3];   // NG(number[] でも string[] でもない)

b = [1, 2, 3];        // OK(number[])
b = ["a", "b"];       // OK(string[])
TypeScript

「要素レベルで混ざる」のが union型配列((A | B)[])、
「配列そのものが2パターンある」のが配列の union(A[] | B[])です。

ここを意識して書けるようになると、型設計の精度が一気に上がります。


union型配列を使うべき場面・避けるべき場面

使うべき場面のイメージ

「この配列には、仕様として複数種類の値が混ざる」と決まっているときに、union型配列は力を発揮します。

ログの配列(数値IDと文字列メッセージが混ざる)

type LogItem = number | string;

const logs: LogItem[] = [1, "start", 2, "end"];
TypeScript

検索結果の配列(ユーザーか記事か、どちらかが入る)

type UserResult = { type: "user"; name: string };
type ArticleResult = { type: "article"; title: string };

type SearchResult = UserResult | ArticleResult;

const results: SearchResult[] = [
  { type: "user", name: "Taro" },
  { type: "article", title: "TypeScript入門" }
];
TypeScript

このように、「混ざること自体が仕様」であり、その仕様を型で表現したいときに union型配列はとても有効です。

避けた方がいい場面のイメージ

一方で、「とりあえず何でも突っ込んでいるだけ」の配列を union型配列でごまかすのは危険です。

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

この配列を見て、「これは何の配列?」と聞かれて、うまく説明できないなら、
本当はオブジェクトや別の構造にした方がいい可能性が高いです。

const user = {
  id: 1,
  name: "Taro",
  isActive: true
};
TypeScript

「異なる型を混ぜたい」と思ったときは、
「それは本当に1つの配列に混ぜるべきか?」
「オブジェクトやタプルの方が自然じゃないか?」
と一度立ち止まるクセをつけると、設計がぐっと良くなります。


初心者がまず身につけたい union型配列の感覚

union型配列の本質は、「この配列には“この中のどれか”だけが入る」という制約を型で表現することです。

(number | string)[] と書いた瞬間に、
「number か string 以外は入れない」
「取り出したときは number | string だから、ちゃんと絞り込んでから使う」
という2つのルールが自動的に生まれます。

大事なのは、「混ぜること」そのものではなく、
「何が混ざるのか」「なぜ混ざるのか」を型で説明できているかどうか。

そこまで言語化できた union型配列は、
ただの“ごちゃ混ぜ配列”ではなく、あなたの仕様をそのまま映した、強いデータ構造になります。

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