본문 바로가기
programming_kr/typescript

Type Script 기초 배우기 5[Generics]

by JSsunday 2021. 10. 14.
728x90

제네릭(Generics)은 타입스크립트에서 function, class, interface, type을 사용하게 될 때 여러 종류의 타입에 대하여 호환을 맞춰야 하는 상황에서 사용하는 문법입니다.

 

A 와 B 가 어떤 타입이 올 지 모르기 떄문에 이런 상황에서는 any라는 타입을 쓸 수도 있습니다.

function merge(a: any, b: any): any{
    return {
        ...a,
        ...b
    }
}

const merged = merge({foo:1}, {bar:1});

 

그런데 이렇게 하면 타입추론이 모두 깨진거나 다름이 없습니다. 결과가 any라는 것은 즉 merged안에 어떤 타입이 들어있는지 알 수 없다는 것입니다.

이런 상황에 generic을 사용하면 됩니다. 제네릭은 다음과 같이 사용합니다.

function merge<A, B>(a: A, b: B): A & B {
  return {
    ...a,
    ...b
  };
}

const merged = merge({ foo: 1 }, { bar: 1 });

 

generic을 사용 할 때는 이렇게 <T>처럼 꺽쇠 안에 타입의 이름을 넣어서 사용하며, 이렇게 설정을 해주면 제네릭에 해당하는 타입에는 뭐든지 들어올 수 있게 되면서, 사용 할 때 타입이 깨지지 않게 됩니다. 만약 함수에 이렇게 제네릭을 사용하게 된다면 함수의 파라미터로 넣은 실제 값의 타입을 활용하게 됩니다.

 

다른 예시로는 아래와 같은 코드가 있는데

function wrap<T>(param: T) {
  return {
    param
  }
}

const wrapped = wrap(10);

 

이렇게 함수에서 제너릭을 사용하면 파라미터로 다양한 타입을 넣을 수도 있고 타입 지원을 지켜낼 수 있습니다.

 

 

interface 에서 Generics 사용하기

이번엔 interface에서 제너릭을 사용하는 방법을 알아봅시다.

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

const items: Items<string> = {
    list: ['a', 'b', 'c']
};

const items2: Items<number> = {
    list : [1,2,3]
}

console.log(items);
console.log(items2);

 

만약 Items<string>라는 타입을 사용하게 된다면, Items 타입을 지니고 있는 객체의 list 배열은 string[] 타입을 지니고 있게 됩니다. 이렇게 함으로써, list가 숫자 배열인 경우, 문자열 배열인 경우, 객체 배열, 또는 그 어떤 배열인 경우에도 하나의 interface만을 사용하여 타입을 설정 할 수 있습니다.

 

Type alias 에서 Generic 사용하기

type에서 제네릭을 사용하는 방법은 방금 interface에서 제네릭을 사용 한 것과 매우 비슷합니다. 방금 작성했던 코드를 type을 사용하는 코드로 변환볼까요?

 

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

const items: Items<string> = {
  list: ['a', 'b', 'c']
};

 

비슷하다 못해 거의 똑같네요.

 

클래스에서 Generics 사용하기

이번에는 class에서 generic을 사용해보죠. Queue라는 class를 만들어봅시다. Queue는 데이터를 등록 할 수 있는 자료형이며, 먼저 등록(enqueue)한 항목을 먼저 뽑아올 수(dequeue) 있는 성질을 가지고 있습니다. (FIFO: First in First out) 

 

Queue를 타입스크립트로 구현해봅니다.

class Queue<T>{
    list: T[] = [];
    get length(){
        return this.list.length;
    }
    enqueue(item: T){
        this.list.push(item);
    }
    dequeue(){
        return this.list.shift();
    }
}

const queue = new Queue<number>();
queue.enqueue(1);
console.log(queue);
queue.enqueue(2);
console.log(queue);
queue.enqueue(341);
console.log(queue);
queue.enqueue(50);
console.log(queue);
queue.enqueue(51);
console.log(queue);
queue.dequeue();
console.log(queue);
queue.dequeue();
console.log(queue);

 

위 코드를 실행하면 아래와 같은 결과가 나옵니다. queue 변수를 선언할 때 Queue classgeneric타입으로 number을 넣어줬기 때문에 queue의 사용할 때는 number 타입을 사용하게 됩니다.

 

 

이로써 간단한 타입스크립트 사용법을 마칩니다.

728x90

댓글