class<T> ジェネリッククラス

最終更新:2026-10-22

class<T> ジェネリッククラス

ジェネリッククラス(class Stack<T>)は「クラスの構造」と「格納するデータの型」を結びつけます。Stack<number> のインスタンスには number しか出入りできません。フィールド、メソッドのパラメータ、メソッドの戻り値がすべて T を参照でき、状態全体が型安全になります。

グループジェネリクス
種類構文
strict モード不要

ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。

📝 構文

class Stack<T> {
  private items: T[] = [];
  push(item: T): void { this.items.push(item); }
  pop(): T | undefined { return this.items.pop(); }
  size(): number { return this.items.length; }
}

const numStack = new Stack<number>();

⚙️ パラメータ

<T>クラスレベルの型パラメータ:new Stack<number>() の時点で確定し、クラス全体で同じ T を共有します
pop(): T | undefined戻り値は T を参照します。空のスタックからは undefined が出て、それを型の上で正直に表現します

戻り値:メソッドの戻り値型はインスタンスの T で確定します。Stack<number> の pop() は number | undefined です。

▶ サンプル

下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:

出力:

2 1
build

(トランスパイル後の実行出力。numStack.push("1") はコンパイルエラーになります——このインスタンスの T は number に固定されています)

💡 ポイント

ℹ️ 説明 T はクラス全体で同じ1つの変数です。push した型のものが pop で出てきます——これがジェネリッククラスと any ベースのコンテナの本質的な違いです。
💡 ヒント 静的メンバーはクラスの T を参照できません。static はインスタンスではなくクラスレベルだからです。静的なロジックをジェネリックにしたい場合は、static メソッドに独自の型パラメータを宣言します。
⚠️ 注意 型パラメータはインスタンス側にのみ効きます。Stack<number> と Stack<string> は互換性のない2つの型で、相互に代入するとエラーになります。
ケースは今後追加予定です。

📚 関連チュートリアル

❓ よくある質問

Q new Stack() と <number> を書かずに済むのはいつですか?
A コンストラクタの実引数から推論できるときです(new Stack([1, 2]) → Stack<number>)。空のコンストラクタでは推論できず Stack<unknown> になるので、その場合は明示的に書くことを推奨します。
Q ジェネリッククラスの継承はどう書きますか?
A サブクラスは T を固定するか(class NumberStack extends Stack<number>)、自分の型パラメータを持ちます(class Box<T> extends Stack<T>)。親のパラメータが子のパラメータで満たせる必要があります。
Q ジェネリッククラスとジェネリックインターフェースの連携はよくあることですか?
A ごく一般的です。interface Repo<T> が契約を定義し、class MemoryRepo<T> implements Repo<T> が実装を提供します——契約と実装の両方がジェネリックのまま保たれ、業務層は正確な型を得られます。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%