Learning
레슨 3 / 8·20분

제네릭

제네릭이란?

제네릭(Generics)은 타입을 매개변수화하여 재사용 가능한 컴포넌트를 만드는 기법입니다. 함수나 클래스가 다양한 타입에 대해 동작하면서도 타입 안전성을 유지할 수 있습니다.

typescript
// 제네릭 함수
function identity<T>(value: T): T {
  return value;
}

const str = identity<string>("hello"); // string
const num = identity(42);              // number (타입 추론)

// 제네릭 배열 유틸리티
function getFirst<T>(arr: T[]): T | undefined {
  return arr[0];
}

const first = getFirst([10, 20, 30]); // number | undefined
const name = getFirst(["a", "b"]);    // string | undefined

제네릭 인터페이스와 제약 조건

typescript
// 제네릭 인터페이스
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

type UserResponse = ApiResponse<User>;
type PostListResponse = ApiResponse<Post[]>;

// 제약 조건 (extends)
function getLength<T extends { length: number }>(item: T): number {
  return item.length;
}

getLength("hello");    // OK — string은 length 있음
getLength([1, 2, 3]);  // OK — 배열도 length 있음
// getLength(42);      // Error — number에는 length 없음
typescript
// 실전 예제: 유틸리티 타입 활용
interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

// Partial — 모든 속성을 선택적으로
function updateTodo(id: number, updates: Partial<Todo>) {
  // ...
}
updateTodo(1, { completed: true });

// Pick — 특정 속성만 선택
type TodoPreview = Pick<Todo, "id" | "title">;

// Omit — 특정 속성 제외
type TodoWithoutId = Omit<Todo, "id">;
💡

TypeScript의 내장 유틸리티 타입(Partial, Required, Pick, Omit, Record 등)은 모두 제네릭으로 구현되어 있습니다. 이를 잘 활용하면 코드 중복을 크게 줄일 수 있습니다.