typescript · high priority
TypeScript Generics & Utility Types
타입 재사용의 핵심 패턴
intermediate 난이도4시간토스카카오네이버당근배민라인
시작 전
이해도
매우 낮음
학습 개요
탄생 배경
쉬운 설명
복잡한 개념을 실생활 비유로 설명합니다.
“요리 레시피”
Generic은 타입을 위한 변수입니다. "재료 X를 볶는 레시피"처럼, X=닭고기면 닭볶음, X=돼지고기면 제육볶음이 됩니다. Array<number>는 "배열 레시피에 number를 넣은 것"으로, 같은 배열 코드가 다른 타입에서 안전하게 재사용됩니다.
핵심 개념
Generic 함수와 제약typescript
1// ❌ any 사용 — 타입 안전성 없음2function identity(arg: any): any { return arg; }34// ✅ Generic 사용5function identity<T>(arg: T): T { return arg; }6const result = identity<string>('hello'); // string 타입7const num = identity(42); // number 타입 자동 추론89// Generic 제약 (extends)10function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {11 return obj[key];12}13const user = { name: '김개발', age: 30 };14getProperty(user, 'name'); // ✅ 'name' | 'age'만 허용15getProperty(user, 'email'); // ❌ 타입 에러
Generic React 컴포넌트typescript
1// 어떤 타입의 데이터도 받을 수 있는 Select 컴포넌트2interface SelectProps<T> {3 options: T[];4 value: T;5 onChange: (value: T) => void;6 getLabel: (option: T) => string;7}89function Select<T>({ options, value, onChange, getLabel }: SelectProps<T>) {10 return (11 <select12 value={String(value)}13 onChange={(e) => {14 const selected = options.find(o => String(o) === e.target.value);15 if (selected !== undefined) onChange(selected);16 }}17 >18 {options.map((option, i) => (19 <option key={i} value={String(option)}>{getLabel(option)}</option>20 ))}21 </select>22 );23}2425// 사용 — User 타입으로 Select 생성26<Select<User>27 options={users}28 value={selectedUser}29 onChange={setSelectedUser}30 getLabel={(user) => user.name}31/>
실무 적용
어떤 상황에서 사용하는가
API 응답 타입이 엔드포인트마다 다를 때, 공통 응답 래퍼와 에러 처리를 Generic으로 통일
어떻게 적용하는가
useFetch<User>(), useQuery<Product[]>()처럼 반환 타입을 Generic으로 명시. TanStack Query의 useQuery<TData, TError>: 성공 데이터 타입과 에러 타입 분리. Zustand의 create<State>(): 스토어 타입을 Generic으로 정의.
흔한 실수와 안티패턴
- Generic 이름을 T, U 대신 의미 있는 이름(TData, TError)으로 사용하면 가독성 향상
- Generic 제약(extends) 없이 복잡한 속성 접근 시 타입 에러 발생
- Conditional Types 과용 시 타입 에러 메시지가 이해하기 어려워짐
면접 질문
중급토스카카오네이버라인
답변 방향 힌트
재사용성, 타입 안전성
반드시 언급할 키워드
- 타입 재사용
- Generic 제약
- Utility Types
예상 꼬리 질문
- Partial<T>를 직접 구현해보세요
- infer 키워드는 어떻게 사용하나요?