TypeScript에서는 객체 구조를 정의할 때 type alias와 interface 두 가지 문법을 사용할 수 있습니다. 처음 입문할 때는 둘이 거의 동일해 보이기 때문에 헷갈리기 쉽습니다. 하지만 실제로는 기능적 차이가 명확하고, 실무에서는 “언제 무엇을 쓰느냐”가 코드의 유지보수성과 확장성에 큰 영향을 줍니다.
타입 별칭(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
- 둘 다 사용해도 되지만 프로젝트 컨벤션을 통일하는 것이 더 중요
