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