TypeScript ジェネリクス入門:<T> の基本と型制約の書き方
ジェネリクス(Generics)は、型を引数として受け取れる仕組みです。同じ処理を異なる型に対して型安全に使い回せます。
なぜジェネリクスが必要か
any を使うと型の恩恵がなくなります。
// any を使う場合:型チェックが効かない
function identity(arg: any): any {
return arg
}
const result = identity(42)
result.toUpperCase() // 実行時エラーだが TypeScript は気づけない
ジェネリクスを使うと、型を保ったまま汎用的に書けます。
// ジェネリクスを使う場合:型が保たれる
function identity<T>(arg: T): T {
return arg
}
const num = identity(42) // num: number
const str = identity("hello") // str: string
基本の書き方
関数名の後に <T> を付けて型引数を宣言します。T は慣習的な名前で、任意の名前を使えます。
function wrap<T>(value: T): { value: T } {
return { value }
}
const wrapped = wrap("hello") // { value: string }
型引数は明示的に指定することもできます。
const result = identity<number>(42)
配列を受け取る例
function first<T>(arr: T[]): T | undefined {
return arr[0]
}
const num = first([1, 2, 3]) // number | undefined
const str = first(["a", "b"]) // string | undefined
interface と type でのジェネリクス
// interface
interface Box<T> {
value: T
label: string
}
const numBox: Box<number> = { value: 42, label: "数値" }
const strBox: Box<string> = { value: "hello", label: "文字列" }
// type alias
type Pair<T, U> = {
first: T
second: U
}
const pair: Pair<string, number> = { first: "age", second: 30 }
型制約(extends)
型引数に制約を付けることで、使えるメソッドや型を絞れます。
// length プロパティを持つ型だけ受け付ける
function getLength<T extends { length: number }>(arg: T): number {
return arg.length
}
getLength("hello") // 5
getLength([1, 2, 3]) // 3
getLength(42) // エラー:number に length はない
特定の型のサブタイプに絞ることもできます。
type Animal = { name: string }
function getName<T extends Animal>(animal: T): string {
return animal.name
}
keyof との組み合わせ
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]
}
const user = { name: "Alice", age: 30 }
const name = getProperty(user, "name") // string
const age = getProperty(user, "age") // number
getProperty(user, "email") // エラー:存在しないキー
よく使うパターンまとめ
| パターン | 書き方 | 用途 |
|---|---|---|
| 基本 | <T> |
型を引数として受け取る |
| 複数の型引数 | <T, U> |
2種類以上の型を扱う |
| 型制約 | <T extends 型> |
使える型を絞る |
| keyof 制約 | <K extends keyof T> |
オブジェクトのキーを安全に扱う |
| デフォルト型 | <T = string> |
省略時のデフォルト型を指定 |
TypeScript の型システム全般については「TypeScript バージョン確認:tsc version コマンドまとめ」も参照してください。