type과 interface를 비교하는 것은 굉장히 잦은 주제이다.
google에 type vs interface라고만 검색하더라도 굉장히 깊이있고 잘 정리된 글들이 많이 나온다.
그래서 이번 글은 그러한 것들을 읽고 기억해야하는 것들을 짧고 굵게 정리해 놓은 글이라고 이해하면 되겠다.
먼저, typescript에서 선언할 수 있는 객체형식의 데이터묶음이라고 생각하면 된다. interface와 type alias(type방식)의 가장 먼저 보이는 차이점은 선언 방식에 있다.
interface Human {
name: string;
age: number;
height: number;
}
type Human = {
name: string;
age: number;
height: number;
interface는 할당 연산자를 사용하지 않는다.
이것은 문법적 차이이고 기능적 차이를 아는 것이 중요하다. 먼저, type alias 방식은 custom Type도 만들 수 있고 원시타입, 객체타입, union타입, tuple도 만들 수 있다.
그에 반해 interface는 한 가지, type만 생성할 수 있다.
// 원시타입
type Name = string;
// 객체
type Korean = { name: Name; koreanAge: number};
type American = { name: Name; internationalAge: number};
// union 타입
type Person = Korean | American;
// tuple 타입
type Data = [number, string];
type은 원시타입, 객체, union, tuple도 만들 수 있지만 interface는 타입 하나만 만들 수 있다.
아무래도 이 둘의 가장 큰 차이점은 extend를 하는 상속과 관련이 있고, 컴파일 될때 동일한 이름의 interface나 type이 있을때 어떻게 되는지이다.
Typescript의 공식문서를 읽어보면 둘다 상속은 가능하다. 문법이 조금씩 다를 뿐이다.
type Animal = {
name: string
}
type Bear = Animal & {
honey: boolean
}
const bear = getBear();
bear.name;
bear.honey;
위의 예시에서 보이는 것처럼 <타입이름> & {}를 하는 방식의 문법으로 확장한다.
interface Animal {
name: string
}
interface Bear extends Animal {
honey: boolean
}
const bear = getBear()
bear.name
bear.honey
interface에서는 extends
라는 키워드를 사용해서 확장한다.
type alias는
&
라는 키워드로 확장하고 interface는extends
라는 키워드를 사용해서 확장한다.
마지막으로 같은 이름으로 선언된 type alias나 interface가 존재할때 일어나는 현상이다.
interface Human {
name: string;
}
interface Human {
height: number;
weight: number;
}
인터페이스의 경우 같은 이름으로 선언된 interface가 있을 경우 컴파일 과정에서 합쳐진다. 따라서 컴파일 후 interface Human은 다음과 같이 변한다고 생각하면 된다.
interface Human {
name: string;
height: number;
wight: nubmer;
}
type의 경우 동일한 이름의 type이 중복 선언되어 있는 경우, Error
가 발생하게 된다.
interface의 경우, 합쳐지고 type의 경우 error가 발생한다.
차이점을 알아보았다. 그러면 typescript을 만드셨던 분들은 어떤 것을 선호할까? 공식문서에는 다음과 같은 글이 있다.
If you would like a heuristic,
use interface until you need to use features from type
.
즉, interface를 주로 사용하고 interface에서 할 수 없는 것들은 type을 써서 하라고 한다.