TypeScriptは、型をパラメータ化するジェネリクスをサポートしています。
下記は型変数Tを使ってジェネリクスを表現した関数です。引数と返り値にTが適用されます。
function identity<T>(arg: T): T {
return arg;
}
引数だけを考えれば、any型と同じですが、返り値の型に指定の型を適用できる点で違いがあります。
これを呼び出すときには次のようにします。
let output = identity<string>("some words")
<>による指定は省略することもできます。この場合は、引数の型から推論されます。
let output = identity("some words")
ジェネリクスの変数からlengthなどを取得したい場合には、ジェネリクスの配列で表現します。
function lists<T>(arg: T[]): T[] {
console.log(arg.length);
return arg;
}
ジェネリクスを使ってインターフェースを表現することもできます。
interface Sample<T> {
(arg: T): T;
}
function someF<T>(arg: T): T {
return arg;
}
let myF: Sample<number> = someF; // someFは、Sampleインターフェースを実装しているため、代入することができる。
上記例では、Sampleインターフェースのジェネリクスの型をnumber型に制限してmyFを定義しています。これは、インターフェース全体のパラメータにジェネリクスを適用する例です。
下記例では、ジェネリクスの型をインターフェースの各メンバ毎に指定します。先述の例の方が、一目でインターフェースのジェネリクスが分かるため、より良いのかもしれません。
interface Sample {
<T>(arg: T): T; // メンバ毎にジェネリクスを指定
}
function someF<T>(arg: T): T {
return arg;
}
let myF: Sample = someF;
また、ジェネリクスはクラスにも適用することができます。
class SomeClass<T> {
someValue: T;
get(): T{
return this.someValue;
}
set(value: T): void {
this.someValue = value;
}
}
var clS = new SomeCalss<string>(); // stringを指定
clS.set("hoge");
console.log(clS.get());
var clB = new SomeClass<boolean>(); // booleanを指定
clB.set(true);
console.log(clB.get());
ジェネリクスは、enumとnamespaceには適用できませんのでご注意ください。
ジェネリクス | TypeScript 日本語ハンドブック | js STUDIO