[TS] 제네릭 인터페이스와 타입 별칭

TIL

제네릭 인터페이스

제네릭은 인터페이스에도 적용할 수 있다. 인터페이스에 타입 변수를 선언하여 사용하면 된다.

interface KeyPair<K, V> {
  key: K;
  value: V;
}

 

그리고, 변수의 타입으로 정의하여 사용할 수 있다.

let keyPair: KeyPair<string, number> = {
  key: "key",
  value: 0,
};

let keyPair2: KeyPair<boolean, string[]> = {
  key: true,
  value: ["1"],
};

이때 주의해야 할 점은, 제네릭 인터페이스는 제네릭 함수와 달리 변수의 타입으로 정의할 때 반드시 <>와 함께 타입 변수에 할당할 타입을 명시해야 한다는 것이다.

제네릭 함수는 매개변수에 제공되는 값의 타입을 기준으로 타입 변수를 추론할 수 있지만, 인터페이스는 마땅히 추론할 수 있는 값이 없기 때문이다.

 

인덱스 시그니처와 함께 사용하기

// 인덱스 시그니쳐 기본 사용
interface NumberMap {
  [key: string]: number;
}

let numberMap: NumberMap = {
  key: -1231,
  key2: 123123,
};

제네릭 인터페이스는 인덱스 시그니쳐와 함께 사용하면 더욱 유연한 객체 타입을 정의할 수 있다.

// 제네릭 인터페이스와 인덱스 시그니쳐 함께 사용하기
interface Map<V> {
  [key: string]: V;
}

let stringMap: Map<string> = {
  key: "value",
};

let booleanMap: Map<boolean> = {
  key: true,
};

Map<V> 인터페이스는 key는 항상 string이지만, value는 타입 변수 V로 유연하게 지정할 수 있다.

 

제네릭 타입 별칭

인터페이스와 마찬가지로 타입 별칭에도 제네릭을 적용할 수 있다.

type Map2<V> = {
  [key: string]: V;
};

let stringMap2: Map2<string> = {
  key: "hello",
};

제네릭 타입 별칭을 사용할 때에도 제네릭 인터페이스와 마찬가지로 타입으로 정의할 때 반드시 타입 변수에 할당할 타입을 명시해야 한다.

 

제네릭 인터페이스 활용 예시

개발자 또는 학생이 이용하는 프로그램이 있다고 가정해보자.

// 타입 정의
interface Student {
  type: "student";
  school: string;
}

interface Developer {
  type: "developer";
  skill: string;
}

interface User {
  name: string;
  profile: Student | Developer;
}
// 유저 변수 생성
const developerUser: User = {
  name: "Woodstock",
  profile: {
    type: "developer",
    skill: "TypeScript",
  },
};

const studentUser: User = {
  name: "Shuroeder",
  profile: {
    type: "student",
    school: "Peanuts School",
  },
};
// 학생 유저만 가능한 기능
function goToSchool(user: User) {
  if (user.profile.type !== "student") {
    console.log("잘 못 오셨습니다.");
    return;
  }

  const school = user.profile.school;
  console.log(`${school}로 등교 완료`);
}

위 코드는 문제없이 작동한다. 그러나 학생만 할 수 있는 기능이 점점 많아진다면, 함수를 선언할 때마다 조건문으로 타입을 좁혀야 하고, 이는 중복 코드가 된다.

 

제네릭으로 해결하기

이럴 때 제네릭 인터페이스를 이용하면 좋다.

interface Student {
  type: "student";
  school: string;
}

interface Developer {
  type: "developer";
  skill: string;
}

interface User<T> {
  name: string;
  profile: T;
}

function goToSchool(user: User<Student>) {
  const school = user.profile.school;
  console.log(`${school}로 등교 완료`);
}

const developerUser: User<Developer> = {
  name: "Woodstock",
  profile: {
    type: "developer",
    skill: "TypeScript",
  },
};

const studentUser: User<Student> = {
  name: "Shuroeder",
  profile: {
    type: "student",
    school: "Peanuts School",
  },
};

goToSchool(developerUser); // ❌ Error
goToSchool(studentUser);   // ✅

User 인터페이스를 User<T> 제네릭 인터페이스로 변경했다. 이제 goToSchool 함수의 매개변수 타입을 User<Student>로 정의하여 학생 유저만 인수로 전달하도록 제한할 수 있다.

 

결과적으로 함수 내부에서 타입을 좁힐 필요가 없어지므로 코드가 훨씬 간결해진다. developerUser를 전달하면 컴파일 단계에서 오류를 감지할 수 있다.

'TIL' 카테고리의 다른 글

[TS] 프로미스와 제네릭  (0) 2025.11.04
[TS] 제네릭 클래스  (0) 2025.11.04
[TS] map, forEach 메서드 타입 정의하기  (0) 2025.11.04
[TS] 제네릭 타입 변수 응용  (0) 2025.11.04
[TS] 제네릭  (0) 2025.11.04
'TIL' 카테고리의 다른 글
  • [TS] 프로미스와 제네릭
  • [TS] 제네릭 클래스
  • [TS] map, forEach 메서드 타입 정의하기
  • [TS] 제네릭 타입 변수 응용
고견
고견
개발 자국 남기기
  • 고견
    개발자국
    고견
  • 전체
    오늘
    어제
    • 분류 전체보기 (157) N
      • Frontend (29)
        • Next.js (16)
        • JavaScript (7)
      • CS (19) N
        • 자료구조 (9)
        • 알고리즘 (5)
        • 운영체제 (4) N
        • 네트워크 (1) N
      • TIL (93)
      • Dev Log (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CS
    algorithm
    바닐라 자바스크립트
    ai 감성 일기장
    문자열
    Trouble Shooting
    Spa
    C
    App Router
    memory
    Pages Router
    클래스
    emotion diary
    typescript
    useState
    javascript
    react
    배열
    generic
    트러블 슈팅
    cs50
    Next.js
    페이지 라우터
    제네릭
    함수 타입
    인터페이스
    알고리즘
    자료구조
    앱 라우터
    타입 좁히기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고견
[TS] 제네릭 인터페이스와 타입 별칭
상단으로

티스토리툴바