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

TypeScript
スポンサーリンク

「タプルの型固定」とは何か

タプルの一番大きな特徴は、「要素の数・順番・型がすべて固定される」ことです。
普通の配列は「number が何個でも」「string が何個でも」という“長さフリー”な構造ですが、タプルは「この位置にはこの型」「要素数はここまで」という制約を型レベルで持ちます。

let user: [string, number] = ["Taro", 20];
TypeScript

この1行で、次のことがすべて決まります。

  • 要素数は必ず2つ
  • 1番目は string
  • 2番目は number

これが「タプルの型が固定されている」という状態です。


要素数が固定されるとはどういうことか

要素が足りなくても、多すぎてもエラーになる

let point: [number, number];

point = [10, 20];      // OK
// point = [10];       // エラー:要素が足りない
// point = [10, 20, 30]; // エラー:要素が多すぎる
TypeScript

ここで TypeScript は、「このタプルは“ちょうど2つの number”でなければならない」と理解しています。
配列だと [10][10, 20, 30]number[] としてはOKですが、タプルでは長さも型の一部です。

「固定長配列」として使える

実質的に、タプルは「固定長配列」として使えます。
「3つだけ」「2つだけ」といった制約を、型で強制できるのが大きなメリットです。

let rgb: [number, number, number] = [255, 128, 0];
// rgb = [255, 128];      // エラー
// rgb = [255, 128, 0, 1]; // エラー
TypeScript

RGB のように「3つで1セット」が決まっているデータには、タプルの型固定がとてもよくハマります。


各位置の型も固定される

順番を入れ替えるとエラーになる

let user: [string, number];

user = ["Taro", 20];   // OK
// user = [20, "Taro"]; // エラー:順番が違う
TypeScript

タプルは「1番目は string、2番目は number」という位置ごとの型まで固定します。
配列のように「全部 number」「全部 string」ではなく、「ここはこれ」という“位置付きの型”です。

アクセスしたときの型も位置で変わる

let user: [string, number] = ["Taro", 20];

const name = user[0]; // string
const age = user[1];  // number
// const x = user[2];  // エラー:そんな位置は存在しない
TypeScript

普通の配列なら user[0]user[1] も同じ型ですが、
タプルは「位置ごとに型が違う」ので、インデックスアクセスしたときの型も変わります。
これが「型が固定されている」ことの実感しやすいポイントです。


タプルの型固定がもたらす型安全性

間違ったデータ構造をコンパイル時に弾ける

固定長タプルにしておくと、「うっかり仕様と違う形のデータを作ってしまう」ことをコンパイル時に防げます。

type Range = [number, number];

function createRange(from: number, to: number): Range {
  return [from, to];       // OK
  // return [from];        // エラー
  // return [from, to, 0]; // エラー
}
TypeScript

「Range は必ず2つの number から成る」という仕様を、型として固定しているので、
将来誰かが間違った戻り値を書いても、その場でエラーになります。

データの一貫性を保ちやすくなる

固定長タプルは、「この構造はこういう形であるべき」という一貫性を保つのに向いています。

type UserRow = [number, string, boolean];

const users: UserRow[] = [
  [1, "Taro", true],
  [2, "Hanako", false],
  // [3, true, "Jiro"], // エラー:型と順番が違う
];
TypeScript

ここでは「id(number)、name(string)、isActive(boolean)」という順番と型が固定されています。
配列のまま書いているのに、実質的には“型付きの行データ”として扱えるわけです。


as const と組み合わせた「より強い型固定」

リテラル値まで固定される

as const を使うと、タプルの「型固定」がさらに強くなります。

const STATUS = ["success", "error"] as const;
// 型: readonly ["success", "error"]
TypeScript

ここでは、

  • 要素数は2つ
  • 1番目は “success”
  • 2番目は “error”
  • 変更不可(readonly)

という、かなりガチガチに固定されたタプルになります。
「この並びそのものが仕様だ」というときには、as const とタプルの組み合わせはとても強力です。


初心者がまず掴んでおきたい「タプルの型固定」の感覚

タプルの型固定は、まとめるとこういう感覚です。

  • 「要素数が決まっている配列」を作れる
  • 「位置ごとに型が決まっている配列」を作れる
  • 「その形から外れたらコンパイル時に即アウト」にできる

だからこそ、

  • 2つや3つの値で1セットの意味を持つデータ
  • 行データ([id, name, isActive] のようなもの)
  • 「この形からズレてほしくない」構造

に対してタプルを使うと、「仕様そのものを型にしている」感覚が手に入ります。

「この2つ(3つ)は、順番と数が決まった1セットだな」と感じたら、
一度 [型1, 型2, 型3] というタプルで書いてみる。
そこから、「型を固定することの気持ちよさ」が、かなりはっきり見えてくるはずです。

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