TypeScriptのジェネリクスでextendsを使う意味が分からない
Taro · 6/23/2026 · 48 views
function foo<T extends string>(x: T) のようなコードを見かけますが、なぜextendsが必要なのか、普通に function foo<T>(x: T) と何が違うのか教えてください。
Taro · 6/23/2026 · 48 views
function foo<T extends string>(x: T) のようなコードを見かけますが、なぜextendsが必要なのか、普通に function foo<T>(x: T) と何が違うのか教えてください。
extendsを付けることで「Tはこの型に当てはまるものに限定する」という制約(constraint)をジェネリクスに課すことができます。
function foo<T>(x: T)だと、Tはどんな型でも受け付けてしまうので、関数の中でxに対してstring特有のメソッド(例えばx.toUpperCase())を呼び出そうとしても、コンパイラは「Tがstringである保証がない」としてエラーを出します。
function foo<T extends string>(x: T)のようにextends stringを付けると、「呼び出し側が渡せるのはstring(またはstringのサブタイプ)だけ」という制約になるので、関数の中で安全にx.toUpperCase()のようなstringのメソッドを呼び出せるようになります。
オブジェクトの型に対してもよく使われていて、例えば
function getId<T extends { id: string }>(obj: T): string { return obj.id }
のように書くと、「idプロパティを持っているオブジェクトなら何でも受け付けるが、idを持っていない型は渡せない」という汎用的だけど安全な関数を作れます。extendsは「制限」というより「その型が持っていることを保証されている機能を使えるようにする」ためのものだと捉えると理解しやすいと思います。
✓ This question has been solved