タプルの基本構文の全体像
タプルは、「要素の数・順番・型が決まっている配列」を表すための構文です。
基本形はとてもシンプルで、
「配列リテラルの [] の中に、位置ごとの型をカンマ区切りで並べる」だけです。
let t: [型1, 型2, 型3, ...];
TypeScriptたとえば、「1番目が string、2番目が number」のタプルなら、こう書きます。
let user: [string, number];
user = ["Taro", 20];
TypeScriptここから、順番・代入・アクセス・応用の流れで見ていきます。
基本構文1:型注釈としてのタプル
位置ごとに型を並べる
タプルの型注釈は、次のように書きます。
let pair: [string, number];
pair = ["width", 100];
TypeScriptこの宣言には、次の意味が含まれています。
1番目の要素は string
2番目の要素は number
要素数はちょうど2つ
なので、次のような代入はすべてエラーになります。
// pair = ["width"]; // 要素が足りない
// pair = ["width", 100, 1]; // 要素が多い
// pair = [100, "width"]; // 型の順番が違う
TypeScript「配列っぽい見た目だけど、実は“位置付きの型”」という感覚を持っておくと、タプルの挙動が理解しやすくなります。
基本構文2:タプルの値の代入とアクセス
正しい順番・正しい型で代入する
let point: [number, number];
point = [10, 20]; // OK
// point = [10]; // NG
// point = [10, 20, 30]; // NG
TypeScriptここでは「2次元座標」を表しているイメージです。
「必ず2つ」「どちらも number」という制約が、型として効いています。
インデックスアクセスの型も位置ごとに変わる
let user: [string, number] = ["Taro", 20];
const name = user[0]; // string
const age = user[1]; // number
TypeScript普通の配列なら user[0] も user[1] も同じ型ですが、
タプルは「位置ごとに型が違う」ので、インデックスアクセスしたときの型も変わります。
存在しない位置を読もうとすると、コンパイルエラーになります。
// const x = user[2]; // エラー:タプルの長さは2
TypeScript基本構文3:タプルの配列(タプルを要素に持つ配列)
「行の集まり」を表現する
タプルは「1行分のデータ」、配列は「行の集まり」として組み合わせると、とてもきれいに表現できます。
type UserRow = [number, string];
const users: UserRow[] = [
[1, "Taro"],
[2, "Hanako"]
];
TypeScriptここでは、
UserRow は「id(number)と name(string)のペア」UserRow[] は「そのペアがたくさん並んだ配列」
という意味になります。
アクセスするときも、位置ごとの型がちゃんと効きます。
const firstUser = users[0]; // [number, string]
const id = firstUser[0]; // number
const name = firstUser[1]; // string
TypeScript基本構文4:タプルと型推論(as const との関係)
そのまま書くと「混ざった配列」として推論される
const user = ["Taro", 20];
// 型: (string | number)[]
TypeScript型注釈を書かないと、「string と number が混ざった配列」として扱われます。
この場合、user[0] も user[1] も string | number になり、位置ごとの意味は失われます。
タプルとして扱いたいなら型注釈か as const
const user1: [string, number] = ["Taro", 20];
TypeScriptまたは、
const user2 = ["Taro", 20] as const;
// 型: readonly ["Taro", 20]
TypeScriptと書くと、「1番目は string、2番目は number」というタプルとして扱われます。as const の場合は readonly も付くので、「順番も中身も変えない前提のタプル」になります。
基本構文5:タプルを使うときの設計の感覚
「位置に意味がある2〜3個のセット」に向いている
タプルは、次のようなものを表現するときに特に気持ちよく使えます。
座標([x, y])
範囲([start, end])
サイズ([width, height])
type Range = [number, number];
const r: Range = [0, 10];
TypeScriptこのくらいのシンプルな「2つセット」「3つセット」なら、
「1番目がこれ、2番目がこれ」と頭に入れたまま扱えます。
逆に、要素が増えすぎたり、意味が複雑になってきたら、
タプルではなくオブジェクトに切り替えた方が読みやすくなります。
まとめ:タプルの基本構文を一言で言うと
タプルの基本構文は、
「[型1, 型2, 型3] のように、配列リテラルの形で“位置ごとの型”を書く」
これだけです。
そこに、
要素数が固定される
位置ごとに型が変わる
存在しない位置はコンパイルエラーになる
という性質がくっついてきます。
「この2つ(3つ)は、順番に意味がある1セットだな」と感じたとき、
一度タプルで書いてみる。
その小さな一歩から、「配列」と「タプル」の使い分けのセンスが、じわじわ育っていきます。
