회사 동료가 제네릭과 관련한 문서를 공유해줘서 읽던 중 예전에는 이해할 수 없었던 코드에 대해 기록해본다.
아래 코드는 배열(스택)의 첫 번째 값을 가져오는 함수이다.
function getFirst<T extends Stack<U>, U>(container: T): U {
const item = container.pop();
container.push(item);
return item;
}
제네릭에서의 T와 U는 서로 모양이 다른 그릇이다. (알파벳은 그냥 T부터 알파벳순)
같은 그릇에는 같은 타입이 들어가는데, 함수를 사용(호출)하는 곳에서 저 T와 U 자리에 무엇이 들어갈지가 결정된다.
getFirst 함수 내에서는 받은 T와 U 타입을 그대로 적용해 로직을 실행할 뿐이다.
// 사용
getFirst<Stack<number>, number)(numberStack);
위의 함수와 모양을 대조해보면 U 자리에 number가 들어가는 것을 알 수 있다.
T 타입이 Stack<U>
를 상속하기 때문에 container: T
라는 코드는 container가 Stack<U>
, 즉 Stack<number>
타입이라는 것이다.
그리고 배열의 첫 번째 값을 뽑아 반환하기 때문에 반환값인 U 자리에도 number가 들어감을 알 수 있다.