TypeScript : Generics


Generics


Genericsは、オブジェクトにタイプが特定されていない場合に複数のタイプに対応するために使用されます.マルチタイプ対応は、オブジェクトの拡張性を向上させ、再利用性を向上させます.

1.any対応タイプの使用


Genericsに加えて、パラメータおよび戻り値のデータ型はanyに対応することができる.この方法を理解してみましょう.
//파라미터 데이터 타입 : any
//반환값 : any
export const fetchData = async (params: any): Promise<any> => {
    //fetch...
};
const datas = fetchData({ url: 'http://localhost:8080/city', query: 'korea' });
上のコードはtypescriptで致命的な欠点を示しています.typescriptを使用するのは、タイプを指定し、戻り値のタイプを導出するためです.
しかしながら、上記のコードでは、datasのデータ型がanyと表示されており、fecth後にサーバから受信したデータ型を推定することはできない.

2.関数とクラスの汎用性


上記の問題を解決するためにGenericsを使用します.使用方法は、オブジェクト名の横に<T>を使用し、オブジェクト内でタイプをTの値に指定します.Tはタイプの略語です.他の文字を使ってもいいです.함수およびclassの使用方法は以下の通りである.

2.1 anyによる関数汎用の作成

interface dataT {
    data: {
        id: number;
        name: string;
        company: string;
    }[];
}

export const fetchData = async <T1, T2>(params: T1): Promise<T2> => {
    const res = await fetch(`${params}`);
    return res.json();
};

const data = await fetchData<string, dataT>('http://localhost:8080/search?city=seoul');
Genericsとして作成されると、IDEは次のように戻り値のデータ型を認識します.

2.2拡張可能なクラスの作成


Genericsがない場合、classを作成するには、各classをtypeで区別する必要があります.これにより、classの再利用性が低下するコードが繰り返される.
class numberQueue {
    list: number[] = [];

    enqueue(item: number) {
        this.list.push(item);
    }
    dequeue() {
        return this.list.shift();
    }
}
class stringQueue {
    list: string[] = [];

    enqueue(item: string) {
        this.list.push(item);
    }
    dequeue() {
        return this.list.shift();
    }
}

const numberQ = new numberQueue();
const stringQ = new stringQueue();

numberQ.enqueue(0);
numberQ.enqueue('a'); // error!
numberQ.enqueue(1);

console.log(numberQ.dequeue()); // 0
console.log(numberQ.dequeue()); // 1

stringQ.enqueue('a');
stringQ.enqueue(1); // error!
stringQ.enqueue('b');

console.log(stringQ.dequeue()); // 'a'
console.log(stringQ.dequeue()); // 'b'
Genericsを使用すると、上記のコードの重複を低減し、再利用性を向上させます.
class Queue<T> {
    list: T[] = [];

    enqueue(item: T) {
        this.list.push(item);
    }
    dequeue() {
        return this.list.shift();
    }
}
const numberQ = new Queue<number>();
const stringQ = new Queue<string>();

3.インタフェースで汎用型を使用する

interface Datas<T> {
    list: T[];
}

const items: Datas<nubmer> = {
    list: [1, 2, 3],
};

4.type aliasにおける汎用型

type Datas<T> = {
    list: T[];
};

const datas: Datas<number> = {
    list: [1, 2, 3],
};

ソース

  • https://jaeyeophan.github.io/2017/12/30/TS-5-Generics-in-TypeScript/
  • https://react.vlpt.us/using-typescript/01-practice.html