TypeScript에서는 코드의 안전성과 유지보수성을 높이기 위해 다양한 타입 정의 방법을 제공합니다. 그 중 interface
와 type alias
는 매우 중요한 도구입니다. 이 두 가지는 유사한 목적을 가지고 있지만, 사용 방법과 적용 방식에 있어서 차이가 있습니다. 이번 글에서는 interface
와 type alias
의 차이점, 장단점, 그리고 적절한 사용 시나리오를 상세히 알아보겠습니다.
1. Interface와 Type Alias의 기본 개념
Interface란?
interface
는 객체의 구조를 정의하는 데 주로 사용되며, 클래스나 함수, 변수 등에서 사용할 타입을 미리 정의할 수 있습니다. 인터페이스는 주로 객체지향 프로그래밍(OOP) 스타일의 코드에서 유용하며, 클래스와 상호작용할 때 사용하기 좋습니다.
interface Person {
name: string;
age: number;
}
const person: Person = {
name: "John",
age: 30
};
위 예제에서는 Person
이라는 인터페이스를 정의하고, 해당 구조를 따르는 객체를 생성했습니다. 객체의 속성인 name
과 age
는 인터페이스로 미리 정의된 타입을 따릅니다.
Type Alias란?
type alias
는 하나 이상의 타입을 정의하는 방법입니다. type
은 타입 별칭이라고도 불리며, 복잡한 타입을 간결하게 표현하거나 유니언(Union) 및 교차(Intersection) 타입을 정의할 때 자주 사용됩니다. 또한 객체, 함수, 배열 등 다양한 타입을 정의할 수 있습니다.
type User = {
name: string;
age: number;
};
const user: User = {
name: "Alice",
age: 25
};
type
은 객체뿐만 아니라 함수 타입, 유니언 타입 등을 포함한 다양한 타입 정의에 활용할 수 있습니다.
2. Interface와 Type Alias의 차이점
두 개념은 유사한 점이 많지만, 몇 가지 중요한 차이점이 존재합니다. 여기서는 확장 가능성, 선언 병합, 유니언 타입 및 교차 타입 지원, 함수 타입 정의 등의 차이점을 살펴보겠습니다.
A. 선언 병합 (Declaration Merging)
interface
는 선언 병합 기능을 가지고 있습니다. 즉, 동일한 이름의 인터페이스를 여러 번 선언하면 그 속성들이 자동으로 병합됩니다. 이 기능은 특히 외부 라이브러리에서 타입을 확장하거나 커스텀 속성을 추가할 때 유용합니다.
interface Person {
name: string;
}
interface Person {
age: number;
}
// 두 인터페이스가 병합되어 하나의 인터페이스가 됨
const person: Person = {
name: "John",
age: 30
};
반면, type alias
는 이러한 병합 기능을 제공하지 않습니다. 동일한 이름으로 다시 타입을 정의하려고 하면 에러가 발생합니다.
type Person = {
name: string;
};
// 오류 발생: 'Person'이 이미 정의됨
type Person = {
age: number;
};
B. 타입 확장 방식
interface
는 extends
키워드를 사용하여 다른 인터페이스를 확장할 수 있습니다. 이를 통해 기존 인터페이스에 새로운 속성을 추가하거나 기존 속성을 재정의할 수 있습니다.
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
const myDog: Dog = {
name: "Buddy",
breed: "Golden Retriever"
};
type alias
는 extends
키워드를 사용하지 않고, 교차 타입(Intersection Type)인 &
연산자를 사용하여 타입을 확장합니다.
type Animal = {
name: string;
};
type Dog = Animal & {
breed: string;
};
const myDog: Dog = {
name: "Buddy",
breed: "Golden Retriever"
};
이 차이로 인해 interface
는 객체지향적 설계에서 더 적합하고, type
은 더 자유롭고 유연한 타입 정의를 할 때 유리합니다.
C. 유니언 타입과 교차 타입
type alias
는 유니언 타입과 교차 타입을 지원합니다. 유니언 타입은 여러 타입 중 하나를 허용하는 타입이고, 교차 타입은 여러 타입을 조합하여 새로운 타입을 만드는 방식입니다.
type ID = string | number;
let userId: ID;
userId = 123; // OK
userId = "abc"; // OK
이러한 유니언 타입은 interface
에서는 지원되지 않기 때문에, 여러 타입을 조합해야 할 때는 type alias
를 사용하는 것이 더 적합합니다.
D. 함수 타입 정의
함수 타입을 정의할 때, type alias
가 더 간결한 문법을 제공합니다.
// interface로 함수 타입 정의
interface Add {
(a: number, b: number): number;
}
const add: Add = (a, b) => a + b;
// type으로 함수 타입 정의
type Add = (a: number, b: number) => number;
const addFunction: Add = (a, b) => a + b;
type alias
는 화살표 함수 문법을 사용하여 간결하게 정의할 수 있기 때문에, 함수 타입을 자주 정의할 경우 type alias
가 더 편리합니다.
3. Interface와 Type Alias의 장단점
Interface의 장점
- 확장 가능성 : 선언 병합을 지원하므로 여러 모듈에 걸쳐 인터페이스를 확장할 수 있습니다. 특히 외부 라이브러리에서 타입을 확장하는 경우 유용합니다.
- 명확한 구조 : 객체 지향 프로그래밍에 익숙한 개발자들에게는 인터페이스 구조가 더 직관적이며, 클래스와 연동하기 쉽습니다.
- 호환성 : 클래스와 함께 사용할 때 특히 유용하며,
implements
키워드를 통해 명확한 객체 구조를 강제할 수 있습니다.
Interface의 단점
- 유니언 타입 지원 부족 : 유니언 타입을 사용할 수 없기 때문에, 복잡한 조합형 타입을 정의할 때 비효율적입니다.
- 함수 타입 정의의 복잡성 : 함수 타입을 정의할 때,
type alias
에 비해 문법이 다소 복잡할 수 있습니다.
Type Alias의 장점
- 간결성 : 함수 타입 정의나 유니언 타입, 교차 타입을 정의할 때 매우 간결한 문법을 제공합니다.
- 유연성 : 유니언 타입과 교차 타입을 통해 복잡한 타입을 유연하게 정의할 수 있습니다. 특히 여러 타입의 조합이 필요한 상황에서 유용합니다.
- 즉시 사용 가능 : 인터페이스보다 간단하고 직관적인 타입 정의가 가능하여, 간단한 타입을 정의할 때 더 유리합니다.
Type Alias의 단점
- 확장성의 제한 : 선언 병합이 불가능하며, 타입을 확장하려면 별도의 조합이 필요합니다.
- 클래스와의 호환성 부족 : 클래스와의 연동이 인터페이스만큼 직관적이지 않으며,
extends
와 같은 명확한 상속 개념이 없어 클래스 기반 설계와는 다소 어울리지 않습니다.
4. Interface와 Type Alias의 적절한 사용 예시
Interface 사용 예시
객체 구조 정의
클래스 기반의 객체 구조를 정의하거나 명확한 타입 검사를 요구하는 경우 interface
가 적합합니다.
interface Person {
name: string;
age: number;
}
class Employee implements Person {
constructor(public name: string, public age: number, public employeeId: number) {}
}
const emp = new Employee("John", 30, 123);
외부 라이브러리 확장
외부 라이브러리의 타입 정의를 확장해야 할 경우 interface
의 선언 병합 기능을 활용할 수 있습니다.
interface Window {
myCustomProperty: string;
}
window.myCustomProperty = "Hello";
Type Alias 사용 예시
유니언 타입 정의
여러 타입을 하나의 타입으로 조합하여 사용할 때는 type alias
가 더 적합합니다.
type ID = string | number;
let userId: ID = 123;
userId = "abc";
함수 타입 정의
함수 시그니처를 정의할 때는 type alias
가 더 간결한 문법을 제공합니다.
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b;
복합 타입 정의
객체에 여러 타입을 혼합하여 정의할 때도 type alias
가 유리합니다.
type User = {
name: string;
age: number;
};
type Admin = User & {
role: string;
};
let admin: Admin = {
name: "Alice",
age: 30,
role: "Administrator"
};
5. 결론
interface
와 type alias
는 TypeScript에서 타입을 정의하는 두 가지 강력한 도구입니다. 이 둘은 목적이 비슷해 보이지만, 각기 다른 특징을 가지고 있으며 적절한 사용 상황이 다릅니다.
interface
는 주로 클래스 기반 설계나 외부 라이브러리와의 상호작용에서 유용하며, 선언 병합을 통해 확장성을 제공하는 장점이 있습니다.type alias
는 유니언 타입과 교차 타입을 포함하여 복잡한 타입을 정의할 때 더 유연하고 간결한 문법을 제공합니다.
결국, 프로젝트의 요구 사항에 따라interface
와type alias
중 적절한 것을 선택하여 사용하는 것이 중요합니다. 객체 지향 프로그래밍에 가까운 구조적 설계에서는interface
가 더 적합하고, 복잡한 타입 조합이 필요할 때는type alias
가 더 적합할 수 있습니다.
'JavaScript & TypeScript' 카테고리의 다른 글
Node.js와 TypeScript에서 환경 변수 관리 (0) | 2024.12.17 |
---|---|
Node.js와 Express에서 JSON 처리하기 (1) | 2024.12.10 |
Express.js에서 CORS 처리 방법 (0) | 2024.12.03 |
Express.js HandlerInterceptor: 개념 소개 (0) | 2024.11.26 |
CI 환경에서 `npm ci` 명령어를 사용해야 하는 이유 (1) | 2024.11.25 |