
지난 포스트에서 인터페이스를 다루면서 타입 별칭과 유사하다고 했습니다. 그리고 인터페이스에서 다룬 내용으로만 봤을때 타입 별칭과의 별다른 차이점도 느껴지지 않았고요.
그래서 인터페이스와 타입 별칭 무엇이 다른지 조금 조사해보았습니다.
인터페이스는 extends를 통해 자신의 확장이 가능합니다. 그러나 타입 별칭은 교집합 & (Intersection) 타입의 형태로 확장이 가능합니다. (본인이 확장이 되는 않는다는 것을 의미)
interfaceinterface Animal { name: string } interface Dog extends Animal { crying(): void; } const dog: Dog = { name: 'Jay', crying() { console.log('멍'); } }; console.log(dog.name); //Jay dog.crying(); //멍
type aliastype Animal = { name: string; } type Dog = Animal & { crying(): void; } const dog: Dog = { name: 'Jay', crying() { console.log('멍'); } }; console.log(dog.name); //Jay dog.crying(); //멍
추가적으로 인터페이스와 타입 별칭간의 확장도 가능합니다.
interface Animal {
name: string;
}
type Dog = Animal & {
crying(): void;
} //타입 별칭이 인터페이스를 확장
또는
type Animal = {
name: string
}
interface Dog extends Animal {
crying(): void;
} //인터페이스가 타입 별칭을 확장
인터페이스와 타입 별칭 모두 함수 시그니쳐를 표현할 수 있지만 구문이 조금 다릅니다.
interfaceinterface Name { name: string; } interface setName { (name: string): void; }
type aliastype Name = { name: string; } type setName = (name: string) => void;
인터페이스는 객체 타입 정의에만 사용할 수 있지만, 타입 별칭은 기본 타입, 객체, 유니온 타입, 튜플, 배열과 같은 다른 타입에서도 이용할 수 있습니다.
동일 스코프에서 타입 별칭은 재정의가 불가능했습니다. 하지만 인터페이스는 동일 스코프에서도 재정의가 가능합니다.
type alias = number;
type alias = string; //불가능!!!
interface Point {x: number}
interface Point {y: number}
const point: Point = {
x = 0;
y = 0;
};
제일 중요한 것은 어떤 것을 선택하든 일관성있는 모습을 보여야한다는 것입니다. 진행중인 프로젝트에서 인터페이스를 주로 사용했다면 인터페이스 위주의 코드를 작성하는 것이 옳다고 할 수 있습니다.
만약 프로젝트를 처음부터 시작하는데, 둘 중 무엇을 선택할지 고민된다면 어떻게 할까요?
이에 대한 해답은 기본적으로 자유롭지만 해당 코드가 외부에 노출되는지에 대한 여부를 고민하는 것 입니다. 외부에 연결될 필요가 있을 경우 확장에 유리한 인터페이스가 좋을것이고 내부적으로만 사용되는 코드가 외부에 열려있는 것은 좋지 않으므로 이럴땐 타입 별칭이 좋다고 할 수 있습니다.