blog-hero-img

TypeScriptジェネリクスをサクッと理解【その4 複数のジェネリクスをつかう】

pen-icon2024.3.16

この記事は約3分で読めます

Profile Pic

この記事の筆者:三好アキ


🔹 専門用語なしでプログラミングを教えるメソッドに定評があり、1200人以上のビギナーを、最新のフロントエンド開発入門に成功させる。

🔹 Amazonベストセラー1位を複数回獲得している『はじめてつくるReactアプリ with TypeScript』著者。


Amazon著者ページはこちら → amazon.co.jp/stores/author/B099Z51QF2



React、Next.js、TypeScriptなどのお役立ち情報や実践的コンテンツを、ビギナー向けにかみ砕いて無料配信中。登録はこちらから → 無料メルマガ登録

TypeScriptのジェネリクスはむずかしい?

この記事はジェネリクスをサクッと解説する全4回の記事の4つ目です

1 → TypeScriptジェネリクスをサクッと理解【その1 型定義に対して使うジェネリクス】

2 → TypeScriptジェネリクスをサクッと理解【その2 functionに対して使うジェネリクス】

3 → TypeScriptジェネリクスをサクッと理解【その3 型定義とfunction両方に対して使うジェネリクス】

*4(本記事)→ TypeScriptジェネリクスをサクッと理解【その4 複数のジェネリクスをつかう】

ジェネリクスを複数使う

次のコードがあったとします。

// main.ts

function example(a: string, b: string){
    return [a, b]
}

console.log(
    example("三島", "由紀夫")
)

abの2つのデータをexampleに渡して実行後すると、ab[a, b]という配列になってreturnされます。

上の例では[三島, 由紀夫]とブラウザのコンソールに表示されます。

TypeScriptが推測してくれているので不要ですが、returnするデータの型を書いてみましょう。

配列のデータがreturnされるので、次のように書きます。

// main.ts

function example(a: string, b: string): [string, string]{   // 追加
    return [a, b]
}

...

さて、ここで次のようなデータを入れようとするとエラーが出ます。2005がnumber型だからです。

// main.ts

function example(a: string, b: string): [string, string]{
    return [a, b]
}

console.log(
    example("三島", "由紀夫")
)

// ⬇追加
console.log(
    example(2005, "谷崎")
)
// ⬆追加

どのような型のデータにもexamplefunctionが対応できるようにするために、ジェネリクスを使いましょう。

まず渡すデータを仮置きのTKに変えます。

本連載1回目でも書きましたが、ここで使う文字は<ArgType><Name>など任意の文字も可です。

// main.ts
                    ⬇変更
function example(a: T, b: K): [string, string]{
    return [a, b]
}

...

渡すデータの型が仮のものになったので、returnするデータの型も仮のものに変える必要があります。

// main.ts
                              ⬇変更
function example(a: T, b: K): [T, K]{
    return [a, b]
}

...

最後に、このfunctionではジェネリクスを使っていると明示するコードを追加します。

// main.ts
                 ⬇変更
function example<T, K>(a: T, b: K): [T, K]{
    return [a, b]
}

...

今回も型の推測によってこの時点でエラーは消えますが、次のように実際の型情報を注入する必要があるケースも存在します。

// main.ts

function example<T, K>(a: T, b: K): [T, K]{
    return [a, b]
}

console.log(
    example<string, string>("三島", "由紀夫")     // 追加
)

console.log(
    example<number, string>(2005, "谷崎")     // 追加
)

React + TypeScript開発においては、型定義に対するジェネリクスとfunctionに対するジェネリクスが同時に使われ、さらにジェネリクスの数も<T>のように1つだけでなく、<T, K, U>などと複数使われることがあります。

ジェネリクスはいつ使う? そして注意点は?

ジェネリクスが欠かせないのは、npmパッケージやライブラリの開発時です。

これらは多くの人が使うものであり、汎用的であることがマストなので、柔軟性を付与できるジェネリクスが活躍するのです。

しかし、ごく限られた人だけ、あるいは自分だけしか使わないファイルやReactコンポーネントにジェネリクスを過度に使うことは、むしろいたずらに抽象度を高め、時間が経って見返すと何をしているのか自分でもわからなくなってしまう可能性を高めます。

ジェネリクスを使うときはこの点に注意しましょう。


2024年3月にReact + TypeScriptの新刊書をリリースしました。

ジェネリクスを含む、基礎から応用までの幅広い範囲をカバーしており、TypeScript + React入門者から、中級者の人にもっとも学びがある内容になっています。

React + TS徹底フォーカス:TypeScriptマスター with React

【TypeScriptをReactでつかうことに徹底フォーカス。2024年の開発現場で必須のスキルを最短で学べる一冊】

販売ページに移動する

Profile Pic

メルマガ配信中
(from 三好アキ/エンジニア)


React、Next.js、TypeScriptなど最新のウェブ開発のお役立ち情報を、ビギナー向けにかみ砕いて無料配信中。
(*配信はいつでも停止できます)