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

제네릭 제약: 자유로운 T에 최소 계약 세우기

~10 min · generics, constraints, extends

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"T가 무엇이든 될 수 있어도 함수가 쓰려는 속성만큼은 갖춰야 해. 제약은 그 최소선을 말해."

제약 없는 T는 아직 모르는 타입

제네릭 매개변수 T에 아무 제약이 없으면 함수 몸에서는 T의 속성을 함부로 읽을 수 없어. 숫자일 수도, null일 수도, 함수일 수도 있기 때문이야. x.length를 쓰고 싶다면 length가 있다는 사실을 계약에 넣어야 해.

T extends { length: number }라고 적으면 문자열, 배열, length 속성을 가진 사용자 객체가 모두 들어올 수 있어. 클래스 상속을 요구하는 것이 아니라 해당 구조에 대입 가능해야 한다는 뜻이야.

K extends keyof T

가장 자주 만나는 제약 가운데 하나는 K extends keyof T야. K는 T에 실제로 존재하는 키만 될 수 있고 반환 타입을 T[K]로 적으면 선택한 속성의 정확한 값 타입까지 이어져. 문자열 키를 아무거나 받는 함수와 달리 오타를 컴파일 단계에서 막아.

제약은 T를 특정 타입으로 바꾸지 않고 최소 능력만 요구해 구체 타입 정보를 보존해. 생성자 계약을 받으면 new C()로 인스턴스를 만들 수 있고, get<T, K extends keyof T>(obj, key)는 실제 객체의 키만 허용하면서 반환값을 T[K]로 연결해. 제약과 호출 자리 추론이 함께 작동하는 대표 패턴이야.

함수 몸에서 사용하는 최소 멤버만 제약에 적고, 나머지 구체 정보는 T가 보존하게 해.

Code

Constraint — 접근 unlock 과 keyof 사용·typescript
// Constraint 없이 — T 의 property 접근 못 함.
function badLen<T>(x: T): number {
  return x.length;     // ❌ Property 'length' does not exist on type 'T'
}

// Constraint 있으면 — string, 배열, length 가진 어떤 거든 작동.
function len<T extends { length: number }>(x: T): number {
  return x.length;
}

len('hello');          // ✅ string 이 length 가짐
len([1, 2, 3]);        // ✅ 배열이 length 가짐
len({ length: 10 });   // ✅ length 가진 object
// len(42);            // ❌ number 가 length 안 가짐

// keyof constraint — 유명한 패턴.
function prop<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: 'Pippa', age: 21 };
const name = prop(user, 'name');   // name: string
const age = prop(user, 'age');     // age: number
// prop(user, 'email');             // ❌ 'email' 이 user 의 key 아님

External links

Exercise

서로 다른 두 객체를 펼쳐 합치는 merge<T, U>를 작성해. 두 타입을 object로 제약하고 결과를 T & U로 선언한 뒤 양쪽 필드가 모두 추론되는지 확인해.
Hint
function merge<T extends object, U extends object>(a: T, b: U): T & U { return { ...a, ...b } }처럼 두 인자를 각각 제약해. 반환 타입은 두 객체의 필드를 모두 보존해.

Progress

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

댓글 0

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

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