はじめに
TypeScriptを勉強していく中で、Genericsに出会いました。今回は、そのGenericsというものがなんなのかまとめました。
TypeScript以外のプログラミング言語にもGenericsはありますが、今回はTypeScriptにおけるGenericsをまとめます。
TypeScriptのGenericsについてまとめてみた
Genericsが何であるか簡単にまとめると、型において引数のようなものを用意し、その引数のようなものを決めたタイミングで型を定義できるものです。Genericsは、関数やクラス、インターフェースに使うことができます。
Genericsを使う場合、型の後に<T>
などを記載します。ここでいうT
が、先ほど述べた「型における引数のようなもの」にあたります。この言葉だけだとピンとこないと思うので、具体例を使って見てみます。
interface Hoge<T> {
value: T;
}
const x: Hoge<string> = { value: "x" }
const y: Hoge<number> = { value: 3 }
上記の場合、変数を宣言するタイミングで型を定義しています。このように、Genericsでは型を定義するタイミングを遅らせることが可能です。
また、Genericsでは初期の型を決めることが可能で、T
の後に初期の型として指定したい型を=
で結びます。初期の型を指定すると、変数等を宣言する際に<型>
を省略することが可能です。今回は初期の型をstring
型とした例を用意しました。
interface Hoge<T = string> {
value: T;
}
const z: Hoge = { value: "z" }
上記の例ではT
のみ定義できるようになっていますが、定義できる型を追加することも可能です。
interface Fuga<T, K> {
value: T;
key: K;
}
const w: Fuga<string, number> = {
value: "w",
key: 5
}
一番最初に示した例では好き勝手に型を定義することが可能ですが、定義する型を絞りたい場合があると思います。その場合、extends
を使うことで定義できる型を制限することが可能です。string
型もしくはnumber
型に互換性がある型しか定義できない例は以下です。
interface Hoge<T extends string | number > {
value: T
}
const a: Hoge<string> = { value: "a" }
const b: Hoge<number> = { value: 4 }
Genericsは関数でも使うことが可能です。使い方としては関数名の後に<T>
を書くことで実現可能です。アロー関数を使う場合も使用可能で、その場合は以下のように書くことができます。
const returnValue = <T>(value: T): T => value;
さいごに
いかがだったでしょうか。今回は簡単にではありますが、TypeScriptのGenericsについてまとめてみました。