"Generic 은 아직 결정 안 한 타입. Caller 가 slot 채워."
Generic 이 해결하는 문제
배열의 첫 element 반환하는 first 함수 쓴다고 상상. Generic 없으면 element 타입마다 하나씩 써 — firstString, firstNumber, firstUser — 또는 any[] 받고 any 반환, 모든 타입 안전 잃어. 둘 다 나빠.
Generic 이 함수를 call site 에서 캡처되는 unknown 타입으로 parameterize 하게 해서 해결. function first<T>(arr: T[]): T — 한 함수, 한 signature. Compiler 가 argument 에서 T 가 뭔지 알아내고 return 타입까지 thread.
Slot 비유
<T> 를 signature 의 slot 으로 생각해. Caller (또는 compiler 가 inference 통해) 가 함수 호출될 때 slot 채워. first([1, 2, 3]) 가 T 를 number 로 채움; first(['a', 'b']) 가 T 를 string 으로 채움. 두 case 다 같은 함수 코드 돌아; type system 이 차이 추적.
Array<T> 가 이거: element 타입에 slot 가진 배열 타입. Array<string> 이 string[]. Array<{ id: number }> 가 object 의 배열. 같은 모양, 다른 채움.
관계-보존 property
Generic 의 killer 기능이 slot 이 signature 전체에 같다는 것. T 가 parameter 와 return 둘 다 나타나면, 호출이 같은 타입이라고 강제. function identity<T>(x: T): T — 너가 넣은 거 그대로 나오고, 타입 보존. 이 관계-추적이 primitive 타입만으론 불가능.