【実務・中級編】 配列型の定義方法(T[]とArray) – TypeScript実践ガイド

TypeScriptの配列型、`T[]`と`Array`の「どっちを使うべきか?」という終わらない議論に終止符を打つ

現場でコードレビューをしていると、必ず一度は議論になるのが「配列の型定義」だ。`const list: string[]` と書くか、`const list: Array` と書くか。

「どっちもコンパイル結果は一緒でしょ?」という認識で止まっているなら、それは少しもったいない。今日は、この二つの記法の決定的な違いと、シニアエンジニアが現場でどう使い分けているのか、その深淵を覗いてみよう。

—

1. そもそもTypeScriptにおける二つの記法の正体

結論から言えば、TypeScriptのコンパイラ(`tsc`)にとっては、この二つは完全に「等価」だ。どちらを選んだとしても、最終的に生成されるJavaScriptには型情報は残らないし、ランダムな最適化が施されるわけでもない。

しかし、なぜ二つの書き方が存在するのか? それは言語設計上の「柔軟性」と「可読性」のバランスを保つためだ。

  • `T[]` (Array Shorthand): JavaScriptの配列リテラル `[]` と同じ記号を使うため、直感的で視認性が極めて高い。
  • `Array` (Generic Interface): `Array` という組み込みのインターフェースを明示的に指定する。他のジェネリック型(`Promise`や`Map`)との構文の一貫性がある。

2. なぜ実務では「T[]」が圧倒的に愛されるのか

現場レベルで言えば、9割以上のケースで `T[]` を選ぶべきだ。理由は単純で、「ノイズが少ないから」に尽きる。

// 悪い例: 括弧と不等号で視覚的にうるさい
const userNames: Array = [‘Alice’, ‘Bob’, ‘Charlie’];

// 良い例: 一目で配列だと分かる。モダンでクリーン。
const userNames: string[] = [‘Alice’, ‘Bob’, ‘Charlie’];

フロントエンドのコードは、ただでさえJSXや複雑なロジックで視覚情報が溢れている。型定義が数文字増えるだけで、コードの「密度」が上がり、認知負荷が増大する。脳のサボり癖を活かすなら、圧倒的に `T[]` だ。

3. それでも「Array`」をあえて選ぶべき例外的なケース

では、`Array` が無用かというと、そうではない。シニアが「あえて」ジェネリック記法を採用するシーンは、主に以下の2つだ。

① 「型自体が複雑」なとき

型の中に型が入れ子になる場合、`T[]` だとどこで括弧が閉じているかを見失うことがある。

// T[] だと少し読みづらい
type Result = (string | number)[][];

// Array を使うと、構造が整理されて見えることもある
type Result = Array>;

このように、多次元配列などで「型を強調したい」場合は、ジェネリック記法の方が構造をハッキリと示せる。

② 「読み取り専用(Readonly)」を意識させる場合

これが現場で最も価値のある使い分けだ。`ReadonlyArray` は、不変性を担保するための強力な武器になる。

// ReadonlyArray を使うと、破壊的なメソッド(pushやsplice)をコンパイル時に防げる
const immutableList: ReadonlyArray = [‘A’, ‘B’, ‘C’];

// immutableList.push(‘D’); // ここで即座にエラー!バグを未然に防ぐ

もちろん `readonly string[]` と書くこともできるが、大規模な型定義の中では `ReadonlyArray` の方が「これは単なる配列ではなく、読み取り専用のリストである」という意図が明確に伝わる。

—

4. 現場で使えるTips:ブラウザの処理とパフォーマンス

「ブラウザが裏側でどう処理しているか」という点において、重要なのは型定義そのものではなく、「実行時のJSエンジン(V8など)がどう最適化するか」だ。

TypeScriptの型が何であれ、生成されるのは単なる `Array` オブジェクトだ。もしパフォーマンスを気にするなら、`Array` か `T[]` かを悩むよりも、「配列の中身を単一の型で統一する(モノモーフィックな配列にする)」ことの方が100倍重要だ。

// V8エンジンは、型が統一された配列を高速に処理する(これを「ホーリー・アレイ」を避けるという)
const numbers: number[] = [1, 2, 3];

// 一方で、雑多な型が混ざると最適化が効きにくくなる
const messy: (number | string | object)[] = [1, ‘2’, { id: 3 }];

まとめ:我々の結論

  • 基本は `T[]` を使え。 これがモダンなTypeScript開発のデファクトスタンダードだ。
  • 多次元配列や読み取り専用の強調が必要な時は `Array` を検討せよ。 意図をコードに込める手段として使い分ける。
  • 型定義よりも「配列の中身の型を統一する」意識を持て。 それこそが、真にパフォーマンスを理解しているエンジニアの思考だ。

TypeScriptは、型を書くための道具ではない。「チーム全員が、コードの意図を瞬時に理解するためのコミュニケーションツール」だ。自分がどちらの記法を選んだとき、チームメンバーが最も読みやすいと感じるか。その視点を持つだけで、君のコードはグッとプロフェッショナルなものになるはずだ。

さあ、エディタを開いて、プロジェクトの型定義を一度見直してみよう。意外なほどスッキリするはずだぞ。

コメント

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