본문 바로가기
FE/TypeScript

[TypeScript] 제네릭

by thedev 2023. 2. 1.

 

제네릭

 


 

 

# 제네릭(Generics)이란?

 

 타입스크립트를 사용하면 변수의 타입을 변경할 수 없다. name: string이라든지, age: number라든지, 변수 선언과 동시에 타입이 지정되기 때문이다. string | undefined 처럼 작성해주면 약간은 유연하게 사용할 수 있으나 기본적으로 타입은 항상 고정되어 있다.

 

 그러나 프로그래밍을 하다보면 변수의 타입이 바뀔 수도 있다, 혹은 하나의 함수에 다양한 타입의 값을 넣어야 할 수도 있다. 이런 경우에는 타입을 고정적으로 지정하면 오히려 불편해진다. 따라서 타입을 직접적으로 고정시키지 않고 변수처럼 언제든지 변할 수 있도록 해주는 장치가 등장하였는데, 이를 제네릭(Generic)이라고 한다.

 

function add(x: string | number, y: string | number): string | number {
   return x + y;
}

add(1, 2); // 3
add('hello', 'world'); // 'helloworld'

 

 숫자 or 글자를 더하는 함수가 있다고 치자. 이때 타입을 string | number라고 지정해주면 될 것 같지만 문제가 있다. string + number 혹은 number + string이라는 경우가 있기 때문이다. 이 경우에는 타입 에러가 발생한다. 이 문제를 해결하기 위해서는 함수를 타입별로 나눠서 각각 선언해주어야 한다. 이를 함수 오버로딩이라고 한다.

 

function add(x: string, y: string): string;
function add(x: number, y: number): number;

function add(x: any, y: any) {
   return x + y;
}

add(1, 2); // 3
add('hello', 'world'); // 'helloworld'

 

 그렇다면 타입스크립트를 사용할 때 항상 함수 오버로딩 방식으로 함수를 이용해야 할까? 그럼 코드가 매우 길어질 것이다. 이로 인해 제네릭이 등장하였다.

 

function add<T>(x: T, y: T): T {
   return x + y;
}

add<number>(1, 2);
add<string>('hello', 'world');

 

 제네릭은 위와 같이 <>를 이용하여 표현한다. T라는 변수로 타입을 변수화하고, 함수를 사용할 때 타입을 지정하는 방식으로 사용한다. 즉, 타입을 변수처럼 선언한 뒤 그때그때마다 원하는 타입을 지정하여 사용하는 방식이다.

 

function example<T>(arr: T[]): T[] {
   console.log(arr.length);
   return arr;
}

example([1, 2, 3]);

 

 배열로 사용하고 싶다면 배열 타입을 같이 선언해주면 된다.

 

 

# interface와 같이 사용하기

 

 제네릭은 인터페이스와 같이 사용되는 경우가 많다. 예시로 알아보자.

 

interface User<T> { 
   name: string;
   age: number;
   option: T;
}

const user1: User<{ id: number; isLoggedIn: boolean }> = {
   name: 'kim',
   age: 20,
   option: { id: 123; isLoggedIn: false },
};

const user2: User<string> = {
   name: 's20',
   price: 900,
   option: 'hello',
};

 

이처럼 interface 내의 변수를 제네릭 타입으로 선언하면 다양한 데이터 자료를 할당할 수 있다.

 


 

참고 자료

https://inpa.tistory.com/entry/TS-%F0%9F%93%98-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Generic-%ED%83%80%EC%9E%85-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0

'FE > TypeScript' 카테고리의 다른 글

[TypeScript] interface와 type의 차이점  (0) 2023.02.25
[TypeScript] TypeScript 알아보기  (0) 2023.01.05