프로그래멍 언어/TypeScript

타입스크립트 interface vs type 뭘 사용하지?...

Toris-dev 2023. 12. 30. 10:12

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 ….. 모두 사용가능합니다. )

 

명명된 타입을 정의해 일관성을 유지합시다!!!