Skip to content

TypeScript ジェネリクス 解説

実務でよく使うジェネリクスのパターンを、用途ごとにグループ化しました。型パラメータの宣言、制約の指定、デフォルト値の設定、条件型による分岐、infer による取得、形状のマッピング。各行のパターンには 1 行の例を添えています。

ジェネリクスとは型パラメータ、つまり呼び出し側が選ぶ型のプレースホルダです。これにより、1 つの関数や型が、精度を落とさず多くの形状に対して機能します。<T> は「ある型 T について」と読みます。その力は、T を制約し、分岐させ、マッピングすることで生まれます。以下のパターンが実務の語彙です。

リファレンステーブル · 28 項目
28 of 28 rows
宣言
呼び出し側が選ぶ型パラメータ。function first<T>(xs: T[]): T
複数の独立した型パラメータ。function pair<T, U>(a: T, b: U): [T, U]
1 つ目の型のキーに紐づく 2 つ目のパラメータ。function get<T, K extends keyof T>(o: T, k: K): T[K]
フィールドとメソッドに型パラメータを持つクラス。class Box<T> { value: T }
型パラメータを持つオブジェクトの形状。interface Result<T> { data: T }
アロー関数での型パラメータ。末尾のカンマは .tsx ファイルが JSX と解釈するのを防ぎます。const first = <T,>(xs: T[]): T => xs[0]
制約
T が Type に代入可能であることを要求します。function len<T extends { length: number }>(x: T)
T を別の型のキーに制約します。type Keys<O> = keyof O
T を new で構築できるクラスに制約します。function make<C extends new () => C>(c: C): C
T が複数の制約を同時に満たすことを要求します。function log<T extends Error & { code: number }>(e: T)
何に対しても制約できます。パラメータを絞り込まずにジェネリックのまま保ちます。type Wrap<T> = T extends unknown ? { v: T } : never
デフォルトと infer
呼び出し側が省略したときの T のデフォルト値を指定します。function parse<T = string>(): T
条件型の内部で型を取得します。type El<T> = T extends Array<infer I> ? I : never
ネストした Promise を内側の型まで展開します。type Data = Awaited<Promise<User>>
テンプレートリテラル型の一部を取得します。type Path<S> = S extends `/api/${infer R}` ? R : never
ユニオン全体を一度に検査します。裸の T は一度に 1 つのメンバーを推論します。type El<T> = [T] extends [Array<infer I>] ? I : never
条件型とマップ型
T が U に代入可能かどうかで型を選択します。type IsStr<T> = T extends string ? true : false
T の各キーを変換して新しいオブジェクト型を構築します。type Frozen<T> = { [K in keyof T]: Readonly<T[K]> }
キーが K、値が V であるオブジェクト。type Scores = Record<string, number>
上記のパターンから派生した組み込みジェネリクス。type Preview = Pick<User, "id" | "name">
extends の前の裸の T はユニオンのメンバーごとに 1 回実行され、結果をユニオン化します。ToArray<'a' | 'b'> = 'a'[] | 'b'[]
マップされたキーに対する修飾子の追加・削除。type Req<T> = { [K in keyof T]-?: T[K] }
ランタイム値のキーを型として取得します。const opts = { a: 1 }; type K = keyof typeof opts
他の文字列型から文字列型を構築します。type Route = `/users/${string}`
タプル型を端から端まで連結します。type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U]
定義が自分自身を参照する型。type Json = string | number | Json[] | { [k: string]: Json }
値を型に対して検査し、より狭いリテラル型を保持します。const c = { dark: "#000" } satisfies Record<string, string>
呼び出し側のリテラル型を拡張せずに保持します(TS 5.0)。function first<const T>(xs: readonly T[]): T