요약
대부분의 경우 type을 사용해도 되고 interface를 사용해도 된다.
복잡한 타입이라면 고민할 것 없이 type을 사용
간단한 객체 타입이라면 일관성과 보강의 관점에서 고려해 봐야 한다. type은 기존 타입에 추가적인 보강이 없는 경우에만 사용한다.
아직 스타일이 확립되지 않은 프로젝트라면 향후에 보강의 가능성이 있을 지 고려 어떤 API에 대한 타입 선언을 작성해야 한다면 interface가 낫다. API가 변경될 때 사용자가 interface를 통해 새로운 필드를 병합할 수 있어 유용하기 때문
그러나 프로젝트 내부적으로 사용되는 타입에 선언 병합이 발생하는 것은 잘못된 설계 따라서 이럴 때는 type을 사용해야 한다.
Type과 Interface의 차이점
일반적으로 type이 interface보다 쓰임새가 많다. type 키워드는 유니온이 될 수도 있고, 매핑된 타입 또는 조건부 타입 같은 고급기능에 활용되기도 한다. 다만 interface는 보강(augment)이 가능하다.
유니온
interface는 유니온 타입 같은 복잡한 타입을 확장하지 못한다. 복잡한 타입을 확장하고 싶다면 type과 &를 사용해야 한다.
type NamedVariable = (Input | Output) & { name: string };
const inVal: NamedVariable = {
input: 500,
name: "Oh",
};
const outVal: NamedVariable = {
output: 1000,
name: "Oh",
};
const inOutVal: NamedVariable = {
input: 500,
output: 1000,
name: "Oh",
};
튜플
interface로도 구현할 수 있지만 type이 더 간단
type Tuple = [number, number];
const tuple1: Tuple = [10, 20];
interface ITuple {
0: number;
1: number;
length: 2;
}
const tuple2: ITuple = [10, 20];
보강(augment)
속성을 확장하는 아래 예제는 선언 병합(declaration merging)이라고 한다. 선언 병합은 주로 타입 선언 파일에서 사용된다.
따라서 타입 선언 파일을 작성할 때는 선언 병합을 지원하기 위해 반드시 interface를 사용해야 하며 표준을 따라야 한다.
type은 기존 타입에 추가적인 보강이 없는 경우에만 사용한다.
interface Person {
age: number;
name: string;
}
interface Person {
job: string;
}
const person: Person = {
age: 30,
name: "woogie",
job: "developer"
}