본문 바로가기
C.W.K.
Stream
Lesson 03 of 07 · published

제네릭 타입과 interface: 재사용 가능한 데이터 틀

~9 min · generics, types, interfaces, data-shapes

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"바뀌는 필드 하나만 타입 매개변수로 들어 올리면, 거의 같은 모양 여러 개가 하나의 계약으로 모여."

타입에 빈칸을 둬

interface Box<T> { value: T }는 어떤 값이든 담는 상자 모양을 한 번 정의해. Box<string>은 문자열 상자, Box<User>는 사용자 상자야. type 별칭도 같은 방식으로 타입 매개변수를 받을 수 있어.

제네릭 타입을 구체화하면 빈칸이 실제 타입으로 치환되고, 그 결과가 평범한 타입처럼 다른 계약 안에 다시 들어갈 수 있어. Promise<PaginatedResponse<User>>처럼 여러 층을 조합해도 원리는 같다.

컨테이너뿐 아니라 결과와 동작도

Result<T, E>는 성공 값 T와 실패 값 E를 가진 판별 가능한 유니언을 만들 수 있어. Reducer<State, Action>은 상태와 행동 사이의 함수 관계를 이름 붙인다. 제네릭은 자료 구조에만 쓰는 기능이 아니라 반복되는 타입 관계의 틀이야.

거의 같은 타입을 복사하지 마

UserResponse, PostResponse, CommentResponse가 items 필드의 원소만 다르고 나머지 pagination 정보가 같다면 각 타입을 손으로 만들 이유가 없어. PaginatedResponse<T> 하나가 관계를 보존하고 공통 구조의 변경도 한곳에서 처리하게 해.

제네릭 별칭과 인터페이스 모두 Pair<T, U> 같은 타입 슬롯을 가질 수 있어. 표준 라이브러리의 Array<T>, Promise<T>, Map<K, V>, Set<T>도 같은 구조야. 컨테이너뿐 아니라 Result<T, E>나 EventHandler<T>처럼 결과와 동작의 관계에도 쓸 수 있어.

여러 타입에서 같은 자리가 반복해서 바뀐다면 그 자리가 타입 매개변수야. 중복을 줄이는 동시에 관계를 이름으로 드러내.

Code

Generic 모양 — Box 와 Result·typescript
// Generic interface — Box 가 뭐든 wrap.
interface Box<T> {
  value: T;
  describe(): string;
}

const boxStr: Box<string> = {
  value: 'hi',
  describe() { return `Box(${this.value})` },
};
const boxNum: Box<number> = {
  value: 42,
  describe() { return `Box(${this.value})` },
};

// Generic type alias — 실패 가능 연산용 Result.
type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

function parseNumber(s: string): Result<number> {
  const n = Number(s);
  return Number.isNaN(n)
    ? { ok: false, error: new Error('not a number') }
    : { ok: true, value: n };
}

External links

Exercise

항목 배열, 전체 개수, 다음 커서를 가진 PaginatedResponse<T>를 정의해. 사용자 페이지를 반환하는 비동기 함수에서 T가 User로 이어지는지 확인해.
Hint
제네릭 타입은 다른 제네릭의 인자 자리에 그대로 들어갈 수 있어. Promise의 성공 값으로 PaginatedResponse<User> 전체를 넣는 구조야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인 — 댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.