Generic ?
- 일단 제네릭이란 일반적인 또는 포괄적인 이라는 뜻을 가지고 있다.
- 즉 제네릭 타입으로 지정을 하면 모든 타입을 지정할 수 있다는 뜻이다.
- 제네릭 타입을 사용 하면 함수나 인터페이스, 클래스 등을 하나의 타입이 아닌 다양한 타입과 함께 동작하도록 만들 수 있다.
- 제네릭 타입은 <>안에 '타입 변수'를 선언하는 방식으로 지정할 수 있다.
- 아래 제네릭 함수 예제를 통해 이해해 보자.
어떤 상황에서 사용해야 하는 거지 ?
- 예를 들어 어떤 함수가 있는데 어떤 값을 인자로 받을 지도 모르겠고, 어떤 값을 리턴 해줘야 될지도 모르겠다면 그냥 any타입으로 지정해 볼 수 있을 것이다.하지만 any타입을 사용하면 타입스크립트를 적용하는 의미가 없어지기 때문에 사용하지 않는 것이 좋다.
- 따라서 해당 함수를 호출 할때 전달하는 인자의 타입을 해당 함수의 타입으로 지정 할 수 있다면 해당 문제를 해결 할 수 있을 것인데, 이때 제네릭 타입을 사용하는 것이다.
- 아래 제네릭 함수 예제를 통해 이해해 보자.
//😀 먼저 인자로 any타입을 받는 함수가 있다.
//😀 인자로 받은 값을 그대로 리턴하고 있으니 함수의 리턴값의 타입도 any타입일 것이다.
function func(value: any) {
return value;
}
//😀 함수에 number를 넣어서 호출 하면 number가 그대로 리턴이 되지만 해당 함수가 any 타입을 리턴 하고 있기 때문에
//😀 변수 num은 any타입으로 추론 된다.
let num = func(10);
//😀 함수에 string을 넣어서 호출 하면 string이 그대로 리턴이 되지만 해당 함수가 any타입을 리턴 하고 있기 때문에
//😀 변수 str은 any타입으로 추론 된다.
let str = func("string");
--------------------------------------------------------------------------------------------
//😀 이번에는 func라는 함수를 제네릭 타입으로 지정해 보자.
//😀 func라는 함수의 타입은 제네릭이고 타입 변수의 이름을 T로 지정 했고 해당 타입을 함수의 인자와 리턴값의 타입으로 지정하면 된다.
function func<T>(value: T): T {
return value;
}
//😀 func함수는 제네릭 타입이기 때문에 함수를 호출 할때 전달 하는 인자의 타입이 해당 함수의 타입이 된다.
//😀 아래의 경우 number타입을 인자로 전달을 했기 때문에, 인자의 타입도 number,
//😀 함수의 리턴값의 타입도 number가 된다. 따라서 num 이라는 변수는 number타입이 된다.
let num = func(10);
//🔥 제네릭 함수를 호출하면 타입이 전달한 인자에 맞에 알아서 지정이 되는데 이렇게 하지 않고 내가 임의로 지정할 수도 있다.
//🔥 아래와 같이 함수를 호출 할때 타입을 지정해 주면 해당 함수의 타입이 되고, 인자의 타입도 지정한 타입이 되고,
//🔥 리턴값의 타입도 지정한 타입이 된다. 따라서 아래의 예제는 인자로 숫자 2개를 전달했으므로 타입 에러가 날 것이다.
let arr = func<[number,number,number]>([1,2])
2개 이상의 타입 변수
- 위의 예제를 보면 타입변수를 T 하나만 지정을 했기 때문에 예를 들어 2개의 서로 다른 타입의 인자를 받게 할려면 타입 에러가 발생 할 수 있다.
- 이때는 타입 변수를 2개 이상 지정해 주면 된다.
//😀 func함수는 제네릭 타입이고, 인자는 2개를 받고 있다.
function func<T>(a: T, b: T) {
return [a, b];
}
//😀 그런데 함수를 호출 할 때 서로 다른 타입의 인자를 전달 하면 어떻게 될까?
//😀 먼저 string타입이 전달이 되었으므로 해당 함수의 타입은 string타입이 된다. 따라서 2번째 인자는 number타입 이기 때문에
//😀 타입 에러가 발생 한다.
const [a, b] = func("1", 2);
//😀 이때는 타입 변수를 2개 이상으로 지정해 주면 된다.
function func<T, U>(a: T, b: U) {
return [a, b];
const [a, b] = func("1", 2);
interface에서 제네릭 사용하기
- interface로 타입을 지정할 때도 제네릭을 사용할 수 있다.
interface Person<T> {
name: T
age: number
}
// 😀 여기서 주의할 점은 그냥 name에 할당된 타입이 추론 되어 제네릭 타입이 되는 것이 아니라
// 😀 반드시 어떤 타입을 넘길 것인지 아래 처럼 입력을 해줘야 한다.
const person: Person<string> = {name:'hdh', age:30}