TypeScript 타입 앨리어스 vs 인터페이스 – 언제 어떤 걸 써야 할까? (7강)
타입 앨리어스(Type Alias)와 인터페이스(Interface)의 차이점
TypeScript에서 객체나 함수의 타입을 정의할 때 주로 사용하는 두 가지 방법은 **타입 앨리어스(type alias)**와 **인터페이스(interface)**입니다. 둘은 비슷한 점이 많지만, 사용되는 상황에 따라 선택해야 할 때가 다릅니다. 이번 강의에서는 타입 앨리어스와 인터페이스의 차이점과 각각의 사용 사례에 대해 설명하고, 언제 어떤 것을 선택해야 하는지에 대해 다뤄보겠습니다.
타입 앨리어스란?
타입 앨리어스는 **기존 타입에 이름을 부여**하는 방법입니다. 타입 앨리어스를 사용하면, 객체, 배열, 함수 등 다양한 타입에 이름을 지정할 수 있습니다. 타입 앨리어스는 주로 복잡한 타입 정의나 유니언 타입, 튜플 등 다양한 타입을 다룰 때 유용하게 사용됩니다.
type Point = { x: number; y: number };
const point: Point = { x: 10, y: 20 };
위 예제에서 Point
라는 타입 앨리어스를 선언하여, x
와 y
속성을 가진 객체 타입을 정의했습니다.
이제 Point
를 사용하여 타입을 재사용할 수 있습니다.
인터페이스란?
인터페이스는 **객체의 구조**를 정의하는 데 사용됩니다. 객체가 가져야 할 속성명과 해당 속성들의 타입을 정의할 수 있으며, 클래스나 객체가 특정 구조를 따르도록 강제할 수 있습니다. 인터페이스는 객체 지향 프로그래밍(OOP)에서 중요한 역할을 하며, 특히 클래스와 결합해 사용할 때 강력한 기능을 제공합니다.
interface Point {
x: number;
y: number;
}
const point: Point = { x: 10, y: 20 };
위 예제에서 Point
인터페이스는 객체의 구조를 정의하고 있습니다. 이 인터페이스를 사용하여 해당 객체가 가져야 할 속성과 타입을 명확히 알 수 있습니다.
타입 앨리어스와 인터페이스의 차이점
타입 앨리어스와 인터페이스는 비슷하지만 몇 가지 중요한 차이점이 존재합니다. 아래에서 주요 차이점을 살펴보겠습니다.
- 확장 가능성:
인터페이스
는 다른 인터페이스를 상속할 수 있으며, 기존의 인터페이스를 확장하여 새로운 타입을 만들 수 있습니다. 반면,타입 앨리어스
는 기본적으로 상속을 지원하지 않으며, 대신유니언
이나교차
타입을 사용하여 복잡한 타입을 생성할 수 있습니다. - 중복 선언: 인터페이스는 동일한 이름으로 여러 번 선언할 수 있으며, 각 선언은 자동으로 병합됩니다. 반면, 타입 앨리어스는 중복 선언이 불가능합니다.
- 사용 용도: 인터페이스는 주로 **객체와 클래스**의 구조를 정의할 때 사용되고, 타입 앨리어스는 **유니언, 튜플, 함수 타입** 등 다양한 복합적인 타입을 정의할 때 더 유용합니다.
인터페이스 확장(상속) 예시
인터페이스는 다른 인터페이스를 확장할 수 있는 기능을 제공합니다. 이를 통해, 하나의 인터페이스가 다른 인터페이스의 속성을 물려받을 수 있습니다.
interface Shape {
color: string;
}
interface Circle extends Shape {
radius: number;
}
const circle: Circle = { color: "red", radius: 10 };
위 예제에서 Circle
인터페이스는 Shape
인터페이스를 확장하여 color
속성뿐만 아니라 radius
속성도 정의할 수 있습니다.
이렇게 인터페이스를 확장함으로써 코드의 재사용성을 높이고, 객체의 구조를 더욱 명확히 할 수 있습니다.
타입 앨리어스의 유니언(Union)과 교차(Intersection) 타입
타입 앨리어스를 사용하면, **유니언(Union) 타입**과 **교차(Intersection) 타입**을 쉽게 정의할 수 있습니다. 유니언 타입은 여러 타입 중 하나를 허용하고, 교차 타입은 두 타입을 결합하여 새로운 타입을 만듭니다.
type Shape = { color: string };
type Circle = Shape & { radius: number }; // 교차 타입
const circle: Circle = { color: "red", radius: 10 };
type ID = string | number; // 유니언 타입
const userId: ID = "12345"; // 숫자도 가능
위 예제에서 Circle
타입은 Shape
와 { radius: number }
를 결합한 교차 타입입니다.
또한 ID
타입은 string
또는 number
를 받을 수 있는 유니언 타입입니다.
타입 앨리어스와 인터페이스 언제 어떤 걸 사용할까?
타입 앨리어스와 인터페이스의 선택은 **사용하려는 목적**에 따라 달라집니다. 일반적으로, 객체의 구조나 클래스에서 사용할 타입을 정의할 때는 **인터페이스**를 사용하고, 보다 복잡하거나 유연한 타입을 정의할 필요가 있을 때는 **타입 앨리어스**를 사용하는 것이 좋습니다.
- 인터페이스 사용: 객체나 클래스의 구조를 정의할 때, 다른 인터페이스를 확장하거나 구현할 때.
- 타입 앨리어스 사용: 유니언, 교차 타입 등 다양한 복합적인 타입을 정의할 때, 타입 이름을 재사용하거나 더 복잡한 타입을 정의할 때.
타입 앨리어스와 인터페이스 선택 가이드
- **객체의 구조를 정의할 때**: 인터페이스가 더 직관적이고 가독성이 좋습니다. 또한 클래스와 결합해 사용하기 유리합니다. - **복잡한 타입을 정의할 때**: 타입 앨리어스를 사용하는 것이 좋습니다. 예를 들어, 유니언 타입, 교차 타입, 함수 타입 등을 정의할 때는 타입 앨리어스가 더 유용합니다. - **인터페이스 확장이 필요할 때**: 다른 인터페이스를 확장해야 할 경우에는 인터페이스를 선택하는 것이 좋습니다.
마무리: 타입 앨리어스와 인터페이스의 활용
타입 앨리어스와 인터페이스는 각각의 용도와 특성에 맞게 사용해야 합니다. 인터페이스는 객체 지향적인 코드에서 객체나 클래스의 구조를 정의할 때 유용하고, 타입 앨리어스는 보다 복잡하고 유연한 타입을 정의하는 데 강력한 도구입니다. 타입스크립트의 강력한 타입 시스템을 이해하고, 적절하게 이 두 가지 방법을 활용하면 코드의 안전성을 높이고 유지보수성을 개선할 수 있습니다.
다음 강의에서는 TypeScript에서 제네릭(Generic)을 사용하여 보다 유연한 코드 작성법을 배워보겠습니다.