어제 오늘 내일

[TypeScript] 5. interface vs type — 무엇을 언제 쓸까 본문

IT/TypeScript

[TypeScript] 5. interface vs type — 무엇을 언제 쓸까

hi.anna 2026. 8. 9. 12:42

이 글의 목표: TypeScript 입문자가 가장 자주 묻는 질문에 실용적인 답을 줍니다. 둘의 공통점, 차이점, 그리고 선택 기준.

둘 다 "이름 붙은 타입"을 만든다

객체 구조에 이름을 붙이는 두 가지 방법입니다. 대부분의 경우 서로 바꿔 써도 됩니다.

// interface 방식
interface User {
  id: number;
  name: string;
}

// type 방식
type UserT = {
  id: number;
  name: string;
};

// 사용법은 완전히 동일하다
const a: User = { id: 1, name: "철수" };
const b: UserT = { id: 2, name: "영희" };

확장(상속) 방법이 다르다

interface: extends

interface Animal {
  name: string;
}

interface Dog extends Animal {
  breed: string;
}

const d: Dog = { name: "바둑이", breed: "진돗개" };

type: 인터섹션(&)

type Animal = { name: string };
type Dog = Animal & { breed: string }; // & 로 합친다

const d: Dog = { name: "바둑이", breed: "진돗개" };

type만 할 수 있는 것

type은 객체뿐 아니라 모든 종류의 타입에 이름을 붙일 수 있습니다. 이게 type의 가장 큰 강점입니다.

// 유니온 타입 (interface로는 불가능)
type Status = "active" | "inactive" | "pending";

// 원시 타입에 별칭
type ID = string | number;

// 튜플
type Point = [number, number];

// 함수 타입
type Handler = (event: string) => void;

// 조건부/매핑 타입 등 고급 타입 (13, 14편에서 다룸)
type Nullable<T> = T | null;

이런 것들은 interface로는 표현할 수 없습니다.

interface만 할 수 있는 것: 선언 병합

같은 이름의 interface를 여러 번 선언하면 자동으로 합쳐집니다.

interface Window {
  title: string;
}

interface Window {
  version: number;
}

// 두 선언이 병합되어 Window는 title과 version을 모두 가진다
const w: Window = { title: "앱", version: 1 };

이 기능은 일상 코드에선 잘 안 쓰지만, 외부 라이브러리의 타입을 확장할 때 유용합니다. 예를 들어 전역 Window 객체에 커스텀 속성을 추가할 때 씁니다.

// 라이브러리가 만든 전역 타입에 내 속성을 얹는다
declare global {
  interface Window {
    myApp: { version: string };
  }
}

type은 같은 이름으로 두 번 선언하면 에러가 납니다.

성능과 에러 메시지

미묘한 차이지만, 대규모 프로젝트에서는 interface가 컴파일러 최적화 면에서 약간 유리하고, 에러 메시지도 더 읽기 좋게 나오는 경향이 있습니다. type의 복잡한 인터섹션은 에러 메시지가 장황해지기도 합니다.

실용적인 선택 기준

복잡하게 고민할 필요 없습니다. 다음 규칙이면 충분합니다.

// 👍 객체의 "모양"을 정의할 때 → interface
interface Product {
  id: number;
  name: string;
  price: number;
}

// 👍 유니온, 튜플, 함수, 유틸리티 등 객체가 아닌 것 → type
type Category = "food" | "toy" | "book";
type Coordinate = [number, number];
type PriceFormatter = (price: number) => string;

한 줄 요약: "객체 모양이면 interface, 그 외에는 type." 팀에 이미 정해진 컨벤션이 있다면 그걸 따르는 게 가장 중요합니다. 일관성이 규칙 자체보다 중요합니다.

정리

  • 객체 타입에 이름 붙이기는 둘 다 가능하고, 대부분 호환된다.
  • type은 유니온·튜플·함수 등 모든 타입에 이름을 붙일 수 있다.
  • interface선언 병합이 가능해 외부 타입 확장에 유리하다.
  • 실용 기준: 객체 모양은 interface, 그 외는 type. 무엇보다 팀 일관성이 우선.

다음 글에서는 type의 진가가 드러나는 유니온과 인터섹션을 깊게 다룹니다.

반응형
Comments