interface vs type
interface
인터페이스는 자체적으로 병합이라는것을 지원해주는데 기본적으로 array 인터페이스는 lib.es5.d.ts 에 정의되어 있고 기본적으로 lib.es5.d.ts 에 선언된 인터페이스가 사용됩니다.
그러나 tsconfig.json의 lib 목록에 es2015를 추가하면 타입스크립트는 lib.es2015.d.ts에 선언된 인터페이스에 병합됩니다.
여기에는 ES2015에 추가된 또 다른 Array 선언의 find
같은 메서드가 포함됩니다.
이들은 병합을 통해 다른 Array 인터페이스를 가집니다.
// type에는 없는 선언병합
interface IState {
name: string;
capital: string;
}
interface IState {
population: number;
}
const wyoming: IState = {
name: 'toris',
capital: 'Cheyenne',
population:500_000
}; // Ok
위 처럼 별도의 2개의 개별적인 선언을 하나의 정의로 병합하는것을 ‘선언 병합’(declaration merging) 이라고 합니다.
type
인터페이스는 타입을 확장할 수 있지만, 유니온 타입은 할 수 없습니다.
그런데 유니온 타입을 확장하는 게 필요할 때가 있습니다.
type Input = { /* .... */ };
type Output = {/* ... */ };
interface VariableMap {
[name: string]: Input | Output;
}
Input과 Output은 별도의 타입이며 이 둘을 하나의 변수명으로 매핑하는 VariableMap
인터페이스를 만들 수 있다.
또는 유니온 타입에 name 속성을 붙인 타입을 만들 수 있다.
type NamedVariable = (Input | Output) & {name: string};
이 타입은 인터페이스로 표현할 수 없습니다.
type 키워드는 일반적으로 interface보다 쓰임새가 많습니다.
type 키워드는 유니온이 될 수 있고, 매핑된 타입 또는 조건부 타입 같은 고급기능에 활용 됩니다.
튜플과 배열 타입도 type 키워드를 이용해 더 간결하게 표현할 수 있습니다.
// Type
type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];
// Interface도 튜플과 비슷하게 구현 가능.
interface Tuple {
0: number;
1: number;
length: string;
}
const t: Tuple = [10, 20]; // ok
그러나 인터페이스로 튜플과 비슷하게 구현하면 튜플에서 사용할 수 있는 concat 같은 메서드들을 사용할 수 없다.
그러므로 튜플은 type 키워드로 구현하는 것이 좋습니다.
결론
type과 interface 의 차이점은 type은 유니온이 될 수 있고 고급기능에 활용되며,
튜플과 배열 타입에 대해서 더 간결하게 표현할 수 있습니다.
interface는 어떤 API에 대한 타입 선언을 작성해야 한다면 인터페이스를 사용하는게 좋습니다.
API가 변경될 때 사용자가 인터페이스를 통해 새로운 필드를 병합할 수 있어 유용하기 때문입니다.
그러나 프로젝트 내부적으로 사용되는 타입에 선언 병합이 발생하는 것은 잘못된 설계입니다.
이럴 때는 type을 사용해야 합니다.
하지만 위에 차이점을 봤을 때 위에 설명한 것들을 빼고는
type 과 interface는 별다른 차이점이 없습니다.
( 제네릭, 인덱스 시그니처, 서로확장, 클래스 implements ….. 모두 사용가능합니다. )
명명된 타입을 정의해 일관성을 유지합시다!!!
'프로그래멍 언어 > TypeScript' 카테고리의 다른 글
[TypeScript] Utility Types (1) | 2024.01.25 |
---|