typescript를 공부하면서 type을 정의하는데 있어서 Type alias
와 Interface
가 있는데 공통된 일을 처리하는 것이 왜 2개나 필요한가 생각들다보니 둘 사이의 차이점
이 궁금했다. 찾고 공부하면서 느낀 것은 둘 사이의 명확한 차이를 제외하고 컨벤션이나 개인의 스타일에 맞게 사용하면 될 것 같다.
일단 내가 공부한 것으로부터 결론부터 내자면 아래와 같다.
interface
로 구현하기. TypeScript can provide terser and more focused messages when working with interfaces
위에서 결론 내린 것에서 중요하다고 생각되는 부분들을 위주로 정리했다.
기본적으로 interface
와 type alias
는 type을 정의하는데 있어서 사용되며 extends, implements
등 공통적으로 가능한 것이 많다.
Interface
interface Person {
name: string;
age: number
}
interface PrintPersonInfo {
(name: string, age: number): void
}
Type alias
type Person = {
name: string;
age: number
}
type PrintPersonInfo = (name: string, age: number) => void;
typescript 팀이 권장하는 방식은 union, tuple
타입을 정의하는 것을 제외하고는 interface
사용을 지향하라고 한다. 그리고 interface
는 객체의 구조
를 설명하는데 사용하라고 추천한다.
아래 코드는 primitive, union, tuple을 type alias로 정의한 것이다.
// primitive type
type InputNumber = number;
type InputString = string;
// union type
type Input = inputNumber | inputString;
// tuple
type Position = [number, number, string];
interface는 open
되어 있고 type alias는 close
되어 있다고 typescript doc에서 말한다. 이는 둘 사이의 가장 큰 차이점이라 생각되며, 뜻만 보면 이해하기 어렵지만 아래의 예시를 참고하면 이해가 쉽다.
// from typescript doc
One major difference between type aliases vs interfaces are that interfaces are open and type aliases are closed.
Interface
interface Person {
name: string
}
interface Person {
age: number
}
interface는 몇 번의 선언을 통해 type을 확장시킬 수가 있다.
Type alias
type Person = {
name: string;
}
// error occurred!!
type Person = {
age: number
}
type alias는 interface와 달리 선언하는 위치해서 해주어야 한다.
type Person = {
name: string;
age: number;
}
📒 type 병합을 interface는 외부에서 가능해 open
이란 개념을 도입하고 type alias는 외부에서 확장이 불가능해 close
라고 함을 알 수 있다.
interface PersonInterface {
height: number;
age: number;
}
type PersonType = { height: number } | { age: number };
class Male implements PersonInterface {
height = 178;
age = 22;
}
// ❌ error occur!!
class Female implements PersonType {
height = 166;
age = 21;
}
📒 type alias를 union type으로 지정하면 class가 implements하는데 오류가 난다. 이는 class나 interface는 static blueprint
로서 고려되기 때문이다.
하지만, 아래와 같이 intersection type으로 type alias
를 선언하는 것은 문제가 없다.
type PersonType = { name: string } & { age: number };
// ⭕️ name과 age를 구현해야된다는 점에서 static blueprint의 조건을 충족한다.
class Person implements PersonType {
name = 'luna';
age = 21
}
위에서 정리한 것에 따라 특정한 상황을 제외하고는 interface를 위주로 사용할 생각이며 가능한 typescript 팀에서 지향하는 방향으로 작성할 생각이다. 또한 공동으로 프로젝트를 할 때도 interface가 유리하다는 생각을 한다. 또한 interface로 구현시 오류의 원인을 보다 정확하게 파악할 수 있기 때문이다.