1. 作品の配列
  2. id 以外のプロパティが増えていても使える
  3. id だけを持つオブジェクト
  4. 空の配列
コース一覧
TypeScript型設計:オブジェクト・状態・ジェネリクス
制約付きジェネリクス

TypeScript型設計:オブジェクト・状態・ジェネリクス

interface、optional property、readonly、union・リテラル型、型ガード、ジェネリクスを扱う全23レッスンの型設計コースです。Profile・Work・ApplicationStateを題材に、APIや画面で扱うデータと状態を壊れにくい型として設計します。既存JavaScriptプロジェクトの移行は次のコースで扱います。

1
オブジェクト型とinterface
01. interface15分
02. 省略可能なプロパティ15分
03. readonly15分
04. interfaceとtype15分
05. ネストした型15分
06. オブジェクト配列15分
07. つくる - Work型とProfile型20分
08. 第4章クイズ15分
2
union・リテラル型・型ガード
01. union型15分
02. リテラル型15分
03. 状態のunion15分
04. typeofで絞り込む15分
05. inと判別で絞り込む15分
06. 状態で表示を切り替える15分
07. つくる - 状態の型表現20分
08. 第5章クイズ15分
3
ジェネリクス入門
01. なぜジェネリクスか10分
02. ジェネリック関数15分
03. 配列を返す汎用関数15分
04. 制約付きジェネリクス15分
05. 組み込みのジェネリクス15分
06. つくる - 汎用フィルタ関数20分
07. 第6章クイズ15分

制約付きジェネリクス

T は「何でもよい」ので、中で何もできない

型引数はどんな型でも受け取れます。裏を返すと、関数の中で使えるものが何もありません。

TypeScript

function collectIds<T>(items: T[]): number[] { return items.map((item) => item.id); } // エラー Property 'id' does not exist on type 'T'.

数値の配列を渡されるかもしれないのだから id があるとは限らない、という指摘です。もっともな話です。

extends で条件を付ける

型引数の後ろに extends と型を書くと、この形を満たす型だけ受け付ける、と宣言できます。これを制約と呼びます。

TypeScript

function collectIds<T extends { id: number }>(items: T[]): number[] { return items.map((item) => item.id); }

これで item.id が読めるようになりました。id が number であることも保証されているので、そのまま number[] として返せます。

条件は下限であって、上限ではない

制約は満たすべき最低条件です。それ以外のプロパティが付いていてもかまいません。

TypeScript

const works = [ { id: 1, title: "プロフィールサイト", published: true }, { id: 2, title: "自己紹介カード", published: false }, ]; collectIds(works); // [1, 2]

条件を満たさない配列は、その場で止まります。

TypeScript

collectIds([{ title: "スキル一覧の表" }]); // エラー Property 'id' is missing in type ...

any との違い

items: any[] と書いても item.id は通ります。ただし通るだけで、id を持たない配列を渡しても止まりません。extends は、必要な条件だけを要求して、残りは自由なままにする書き方です。要求が具体的なぶん、Work でも Profile でも id さえあれば同じ関数が使えます。

手を動かす

演習では、id を持つオブジェクトの配列から id だけを取り出す関数を書きます。いまは制約が無いためエラーになっています。エラーメッセージを読んで、足りない条件を書き足してください。

要件

  1. 型引数に制約を付けて、数値の id を持つ型だけを受け取れるようにする
  2. 戻り値は数値の配列にする
  3. any は使わない

入出力例

collectIds([{"id":1,"title":"プロフィールサイト"},{"id":2,"title":"自己紹介カード"},{"id":3,"title":"スキル一覧の表"}]) → [1,2,3] collectIds([{"id":10,"published":true,"title":"プロフィールサイト"}]) → [10] collectIds([{"id":5},{"id":6}]) → [5,6] collectIds([]) → []

ヒント

制約は型引数の名前の後ろに `extends` と書いて続けます

要求したい形は、数値の `id` を 1 つ持つオブジェクトです

オブジェクトの形は、第4章で書いたインラインのオブジェクト型と同じ書き方で並べます

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/06

関連レッスン

  • 組み込みのジェネリクス

    fetch結果の型を読み解き、ArrayやPromiseの型引数を読めるようになります。

  • つくる - 汎用フィルタ関数

    filterBy関数を型引数付きで完成させ、型安全な汎用処理を書けるようにします。

  • 第6章クイズ

    ジェネリクスと型の制約の理解を確認します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 引数位置引数=順番で渡す。
  • 関数処理に名前を付けて再利用できる単位
  • 配列サイズ固定の同型データの集まり
  • プロパティメソッドを属性のようにアクセスできるようにするデコレータ。
  • オブジェクトキーと値のペアで構造を作るデータ
  • エラーメッセージプログラムが出す失敗の通知
  • 戻り値呼び出し元への返答を表す点線矢印
main.ts
学習モード
エディタを読み込んでいます

メモ

制約付きジェネリクス

⌘S で保存