[TYPESCRIPT] 타입 별칭(type alias) vs 인터페이스(interface) — 언제 어떤 것을 사용해야 할까?

TypeScript에서는 객체 구조를 정의할 때 type aliasinterface 두 가지 문법을 사용할 수 있습니다. 처음 입문할 때는 둘이 거의 동일해 보이기 때문에 헷갈리기 쉽습니다. 하지만 실제로는 기능적 차이가 명확하고, 실무에서는 “언제 무엇을 쓰느냐”가 코드의 유지보수성과 확장성에 큰 영향을 줍니다. 

 

타입 별칭(type alias)란?

타입 별칭은 어떤 타입에 이름을 붙이는 문법입니다. 단순 객체 구조뿐 아니라 Union, Tuple, Function 타입 등 모든 타입을 정의할 수 있다는 점이 큰 장점입니다.

type User = {
  id: number;
  name: string;
};

type은 “타입 = 값”을 매핑한다고 볼 수 있으며, 매우 유연한 타입 조합에 사용됩니다.

 

인터페이스(interface)란?

인터페이스는 객체의 구조(Shape)를 정의하는 문법입니다. 특히 확장성(extends)에 특화되어 있어, 객체 중심 설계(OOP)에서 매우 강력합니다.

interface User {
  id: number;
  name: string;
}

interface는 속성, 메서드, 호출 시그니처 등을 자연스럽게 표현할 수 있어 객체 설계 중심 프로젝트에서 필수 도구입니다.

 

공통점 — 둘 다 객체 구조 정의 가능

대부분의 상황에서 type과 interface는 동일한 객체 구조를 정의할 수 있습니다.

type Point = { x: number; y: number; };

interface Point2 { x: number; y: number; }

따라서 단순 객체를 표현할 때는 둘 중 무엇을 사용해도 문제가 없습니다.

 

주요 차이점

1. type은 모든 타입을 표현할 수 있다

type은 객체뿐 아니라 Union, Intersection, Tuple, Primitive 등 모든 타입을 표현 가능하며 매우 강력합니다.

type ID = number | string;
type Pair = [string, number];
type Fn = (x: number) => string;

interface는 이런 표현을 할 수 없습니다.

 

2. interface는 extends를 통한 확장성이 뛰어나다

interface는 상속 구조를 기반으로 객체 타입을 확장할 때 자연스럽고 직관적입니다.

interface Animal {
  name: string;
}
interface Dog extends Animal {
  breed: string;
}

type도 가능하지만 intersection(&)을 사용해야 하므로 다소 복잡합니다.

type Animal = { name: string };
type Dog = Animal & { breed: string };

 

3. interface는 중복 선언 병합(Declaration Merging)이 가능하다

동일한 이름의 인터페이스를 여러 번 선언하면 TypeScript가 자동으로 병합합니다.

interface User {
  id: number;
}
interface User {
  name: string;
}

const u: User = { id: 1, name: "Alice" };

type은 절대 중복 선언할 수 없어 오류가 발생합니다.

 

4. type이 더 복잡한 타입 조합에 강하다

예를 들어 아래와 같은 “유니온 기반 타입 디자인”은 interface로 불가능합니다.

type Shape = 
  | { kind: "circle"; radius: number }
  | { kind: "square"; size: number };

실무에서 discriminated union 패턴을 많이 사용하기 때문에 type의 활용도가 매우 높습니다.

 

어떤 것을 사용해야 할까? — 실무 기준

✔ 객체 중심 설계(OOP 기반) → interface 추천

  • 도메인 모델 설계
  • 클래스와 함께 사용하는 타입
  • 확장 가능한 구조를 만들 때
  • 라이브러리의 타입을 보강(declaration merging)해야 할 때

✔ 복잡한 타입 조합이 필요할 때 → type alias 추천

  • Union 타입 설계
  • Intersection 타입 조합
  • Tuple 타입 정의
  • Function 타입 선언
  • 기존 타입 변형 및 매핑

 

type과 interface 비교 표

기능 type alias interface
객체 타입 선언 가능 가능
Union/Intersection 가능 불가능
Tuple 타입 가능 불가능
확장(extends) 가능하지만 복잡(& 사용) 직관적이고 강력
중복 선언 병합 불가 가능
선언적 모델링 유연 객체 중심에 최적화

 

실무에서 가장 추천되는 조합

대부분의 프로젝트에서 다음 기준으로 선택하는 것이 가장 깔끔하고 유지보수에 유리합니다.

1. 도메인 객체, API 모델 → interface

interface User {
  id: number;
  name: string;
}

2. 함수 타입 정의 → type alias

type Callback = (msg: string) => void;

3. Union 타입 기반 처리 → type alias

type Result = "success" | "fail";

4. 확장성 있는 모델 → interface (extends)

type alias와 interface는 서로 대체 가능해 보이지만, 각각 장단점과 특화된 용도가 있습니다. 가장 중요한 원칙은 다음과 같습니다.

  • 객체 중심 설계 → interface
  • 유연한 타입 조합·Union 기반 모델 → type alias
  • 둘 다 사용해도 되지만 프로젝트 컨벤션을 통일하는 것이 더 중요