[Typescript] 제네릭 활용

Bam·2023년 9월 2일
0

Typescript

목록 보기
29/32
post-thumbnail

지난 포스트에서 제네릭이 무엇인지에 대해 알아보았습니다. 그리고 제네릭은 함수, 인터페이스, 클래스, 타입 별칭에도 사용할 수 있다고 했었습니다.

그리고 예시를 함수로만 들었었는데 함수만 하고 넘어가긴 좀 그런거 같아서 인터페이스, 클래스, 타입 별칭에서 제네릭을 어떻게 사용하는지도 소개하고자 합니다.


제네릭 인터페이스

제네릭 인터페이스는 다음과 같이 정의합니다. 인터페이스 이름 뒤에 꺾쇠 열고 타입 변수를 선언합니다.

interface 인터페이스_명<타입_변수> {}

제네릭 인터페이스를 사용할 때는 반드시 꺾쇠 안에 타입을 지정해 주어야 합니다. 인터페이스는 타입 추론을 할만한 여지가 없기 때문에 타입을 지정하지 않으면 예상치 못한 동작이 발생하기 때문입니다.

interface Point<X, Y> {
  x: X;
  y: Y;
}

let point: Point<number, number> = { //반드시 타입 지정!
  x: 1,
  y: 1,
};

인덱스 시그니쳐

인터페이스에서는 인덱스 시그니쳐 문법을 사용할 수 있었던 것 기억 하시나요? 제네릭 인터페이스에서도 인덱스 시그니쳐를 사용할 수 있습니다.

interface KeyPair<V> {
  [key: string]: V;
}

let stringKeyPairs: KeyPair<string> {
  key: 'aaa',
};

let numberKeyPairs: KeyPair<number> {
  key: 1,
}

기존의 인덱스 시그니쳐에서는 한 번 정한 타입으로만 선언할 수 있었지만, 제네릭 인터페이스를 이용하면 value에 사용되는 타입이 선언 과정에서 정의되므로 더욱 자유로운 용법으로 사용할 수 있습니다.


제네릭 클래스

제네릭 클래스는 다음과 같이 정의합니다.

class 클래스_명<타입_변수> {}

제네릭 클래스는 비슷한 내용의 클래스를 간편하게 정의할 수 있게 해줍니다. 예를들면 다음과 같이 숫자 리스트와 문자열 리스트 두 개의 클래스를 만들어야하는 상황을 단 하나의 클래스 정의로 해결하게 해줍니다.

class stringDataList {
  constructor(private list: string[]) {}
  
  (...)
}

class numberDataList {
  constructor(private list: number[]) {}
  
  (...)
}
class dataList<T> {
  constructor(private list: T[]) {}
  
  (...)
}

let dataList1 = new List(['', '', '']);
let dataList2 = new List([1, 2, 3]);

이처럼 제네릭 클래스를 정의하면 전달하는 데이터 값에 따라 자동적으로 타입 추론을 해서 하나의 클래스로 여러 타입의 인스턴스 객체를 만들어낼 수 있습니다.


제네릭 타입 별칭

제네릭 타입 별칭은 다음과 같이 정의합니다.

type 타입_별칭_명<타입_변수> = {};

제네릭 타입 별칭 또한 정의 과정에서 타입 변수에 타입을 명시해주어야 합니다.

type Point<X, Y> = {
  x: X;
  y: Y;
};

let point: Point<number, number> = { //반드시 타입 지정!
  x: 1,
  y: 1,
};

0개의 댓글