TypeScript ジェネリクス

TypeScript ジェネリクス

いまさらながらTypeScriptに入門

2022-01-30TypeScript

ジェネリクス概要

クラス、関数、インターフェースに対して後から特定の型を指定できる。

  • クラス クラスにジェネリクスを定義する場合クラスの後に<T>を記述
// valueとgetValueの戻り値型はインスタンス定義時に指定できるようにする
// 型引数(抽象的な型)後から型を定義できる
class MyClass<T>{
    val!:T;
    getValue():T{
        return this.val;
    }
}

// インスタンス作成時に型引数を指定
// 型引数に「string」を指定
let valA = new MyClass<string>();
valA.val='AAA';

// number型で定義
let valB = new MyClass<number>();
valB.val = 4;
  • 関数の場合 関数名の後に<T>を記述
// 関数定義時には引数、戻り値を型引数Tとしておき、実行時に型指定できるようにする。
function test<T>(val:T):T{
    return val;
}

// test実行時に型引数を指定する
console.log(test<number>(3));
console.log(test<string>('テスト'));


// アロー関数の場合の定義
let test2 = <T>(val:T):T => {
    return val;
}
  • インターフェースの場合
// プロパティの型を型引数Tとしておき、定義時に型指定できるようにする。
interface IntA<T> {
    name:string;
    val: T;
}

// 代入時にvalの型を指定
let obj: IntA<number> = { name: "よしお", val: 32 };

// 代入時にvalの型を指定
let obj2: IntA<String> = { name: "よしみつ", val: '57歳' };

型引数を複数指定

型引数指定時に「,」で複数指定できる

// 引数の型引数を複数指定
function test<T, R>(val:T, arg:R):string{
    return `${val}${arg}`;
}

// 実行時にそれぞれの型引数を指定する
console.log( test<string, number>('文字列',55) );//文字列と55

型引数の規定値

型引数を指定しなかった場合には規定値を指定できる/<T=string>

// クラスにジェネリクスを定義する場合クラスの後に<T>を記述
// MyClassには型引数を2種類(T,R)指定、Rを指定しなかった場合はboolean|numberになる
class MyClass<T, R = boolean|number>{
    val!:T|R;//valはTまたはR型で定義
    getValue():T|R{
        return this.val;
    }
}
// Tをstring型で定義、Rをnumber型で定義
let valA = new MyClass<string, number>();
valA.val='AAA';
valA.val=3;

// Tをnumber型で定義、Rは未設定(規定値のboolean|numberになる)
let valB = new MyClass<string>();
valB.val = 4;
valB.val = true;
valB.val = '文字列';

型引数に制約をつける

実行時に渡す型引数を特定の型にしたいときに

// name,ageを持つ型を指定
interface IntA {
    name:string;
    age: number;
}

// 引数の型は後で指定できるがIntAを満たす型のみに絞る
function getName<T extends IntA>(arg:T):string{
    return `名前:${arg.name}${arg.age}`;
}

// name、ageプロパティがあるので実行可能
console.log( getName( {name:'よしお', age:21, area:'関東'} ) );//名前:よしお、21歳

// ageがないためエラーとなる
// console.log( getName( {name:'よしお'} ) );

```