function findById<T>(items: T[], id: string) と書いたら、中で item.id を読むところでエラーになりました。どうしますか。
T extends { id: string } と制約を付けます。制約が無いと T には何でも入りうるので、id があるとは言えません。戻り値は T のままなので、呼び出し側の型も保たれます。
面接官が見ているのはジェネリクスの制約(extends)を使えるか。
よくある答えと、面談でどう見られるか
- T extends { id: string } と制約を付け、id を持つ型だけを受け付けるようにする
その通りです。T が何でもありうる以上、id があるとは言えないので、制約で約束させます。 - item を any にキャストして id を読む
エラーは消えますが、id を持たない型が渡されても止まりません。ジェネリクスにした意味がなくなります。 - T を使うのをやめて、引数を any[] にする
戻り値の型まで any になり、呼び出し側の型が失われます。 - item.id の代わりに item["id"] と書く
書き方を変えても、T に id があると分からない点は同じです。
模範解答
T extends { id: string } と制約を付けます。
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
return items.find((item) => item.id === id)
}制約が無いと、T には number でも何でも入りうるので、id があるとは言えません。extends で「id を持つ型だけ」と約束させると、関数の中で item.id を読めるようになり、id を持たない配列を渡すと呼び出し側でエラーになります。
戻り値は T のままなので、User[] を渡せば User | undefined が返ります。any にすると、この型の情報が全部失われます。
出典(一次資料)
対象: TypeScript 5.x〜7.0 照合した一次資料: 公式ドキュメント 照合: 2026-10-25 最終更新: 2026-10-25
お使いの版で挙動が違う場合があります。誤りに気づいたらこの解説を報告するから教えてください。
ここからどう深掘りされるか
この問いに答えられた場合、面談は次の質問に進みます。
観点をすべて押さえられた場合
条件型が何重にも入れ子になった型があり、誰も中身を説明できません。どう扱いますか。一部しか触れられなかった場合
ジェネリクスの型引数 T は、関数の中ではどういう型として扱われますか。触れられなかった場合
ジェネリクスの型引数 T は、関数の中ではどういう型として扱われますか。