TypeScriptジェネリクスをサクッと理解【その3 型定義とfunction両方に対して使うジェネリクス】
2024.3.16
この記事は約3分で読めます

この記事の筆者:三好アキ
🟢 専門用語なしでプログラミングを教えるメソッドに定評があり、1200人以上のビギナーを、最新のフロントエンド開発入門に成功させる。
🟢『はじめてつくるReactアプリ with TypeScript』、『動かして学ぶ!Next.js/React開発入門(翔泳社/*韓国でも出版)』著者。
▼ Amazon著者ページはこちら
amazon.co.jp/stores/author/B099Z51QF2
最初にお知らせです。
【他に類のないTypeScript + React教材】をリリースしました。
▼ 購入はこちらから
👉 monotein.base.shop/p/00006(Baseショップ)
👉 monotein.booth.pm/items/5611944(Boothショップ)
TypeScriptのジェネリクスはむずかしい?
この記事はジェネリクスをサクッと解説する全4回の記事の3つ目です
1 → TypeScriptジェネリクスをサクッと理解【その1 型定義に対して使うジェネリクス】
2 → TypeScriptジェネリクスをサクッと理解【その2 functionに対して使うジェネリクス】
*3(本記事)→ TypeScriptジェネリクスをサクッと理解【その3 型定義とfunction両方に対して使うジェネリクス】
4 → TypeScriptジェネリクスをサクッと理解【その4 複数のジェネリクスをつかう】
型定義とfunction両方のジェネリクス
次のfunctionがあったとします。
// main.ts
function example(b: any){
return b.data
}これは、渡されたbというany型のデータをreturnするだけのfunctionですが、b.dataとなっているところから、bはオブジェクトだとわかります。
実際の動きを見るには、次のコードを追加しましょう。
// main.ts
// ⬇追加
const userOne: any = {
data: "太郎",
color: "赤"
}
// ⬆追加
function example(b: any){
return b.data
}
// ⬇追加
console.log(
example(userOne)
)
// ⬆追加そしてJavaScriptに変換して実行すると、ブラザウのコンソールには「太郎」と表示されます。b.data、つまりuserOne.dataは「太郎」だからです。
ここで次のデータを足してみます。ここからは1回目で触れた「型定義のジェネリクス」の復習となります。
// main.ts
const userOne: any = {
data: "太郎",
color: "赤"
}
// ⬇追加
const userTwo: any = {
data: 2002,
color: "緑"
}
// ⬆追加
function example(b: any){
return b.data
}
console.log(
example(userOne)
)
// ⬇追加
console.log(
example(userTwo)
)
// ⬆追加anyとなっているところにジェネリクスを使って型情報を追加しましょう。まずuserOneとuserTwoの型定義です。
繰り返しになりますが、ここでジェネリクスを使う理由は、stringとnumberという異なる型がdataに入っているuserOne、userTwo両方に適用可能な柔軟な型定義を作るためです。
// main.ts
// ⬇追加
type User<T> = {
data: T;
color: string;
}
// ⬆追加
const userOne: User<string> = { // 追加
data: "太郎",
color: "赤"
}
const userTwo: User<number> = { // 追加
data: 2002,
color: "緑"
}
function example(b: any){
...次はfunctionのanyを修正しましょう。
まずbというオブジェクトに型定義Userを当てはめます。
function example(b: User){
return b.data
}次のエラーが出ます。
「Generic type 'User' requires 1 type argument(s)」とは「Userには型引数がひとつ必要です」という意味なので、型引数である<T>を追加します。
function example(b: User<T>){
return b.data
}returnするデータの型も追加します。
returnするb.dataは、userOneであれば「太郎」というstring、userTwoであれば「2002」というnumberといったように定まっていないので、「型はあとで決める」という柔軟さを得られるジェネリクスを使い、次のように書きましょう。
function example(b: User<T>): T{
return b.data
}最後に、このfunctionがジェネリクスを使っていることを明示する必要があるので、さらにもうひとつTを書き足します。
function example<T>(b: User<T>): T{
return b.data
}これが型定義とfunctionの両方にジェネリクスを使ったケースになります。
いまコード全体は次のようになっています。
// main.ts
type User<T> = {
data: T;
color: string;
}
const userOne: User<string> = {
data: "太郎",
color: "赤"
}
const userTwo: User<number> = {
data: 2002,
color: "緑"
}
function example<T>(b: User<T>): T{
return b.data
}
console.log(
example(userOne)
)
console.log(
example(userTwo)
)ジェネリクスは複数使うこともできるので、本連載の最後に見てみましょう。
【他に類のないTypeScript + React教材】をリリースしました。
▼ 購入はこちらから
👉 monotein.base.shop/p/00006(Baseショップ)
👉 monotein.booth.pm/items/5611944(Boothショップ)
▼【無料フロントエンド・ガイド】は下記ページで受け取れます。

🟩 フロントエンド開発者入門ガイド【無料配布中】
最初にこれが知りたかった!
フロントエンド初心者が必ず押さえておきたい ― 『挫折しない勉強法』とその具体的ステップ、無料配布中。
(*名前不要・メールアドレスだけで受け取り可能です)


