[TS] type과 interface 당신의 선택은?

황준승·2022년 9월 13일
2

📌 type과 interface

타입스크립트에는 type을 명시하는 두 가지 방법이 존재한다.
바로 typeinterface이다.
하지만 typeinterface로 타입을 지정해 보았을 때 별다른 차이점이 없다는 것입니다.

// 1. type, interface 객체 타입 지정 방식이 동일하다. 
type TState = {
  first: number,
  second: number
}

interface IState {
  first: number,
  second: number
}

// 2. type, interface 둘 다 인덱스 시그니처 사용이 가능하다. 
type TIndexState = {
  [k in string]: number
}

interface IIndexState {
 [k in string]: number
}

// 3. 함수 타입도 type, interface 둘 다 사용 가능하다.
type TFn = (x:number) => string;
interface IFn {
  (x:number) : string;
}

// 4. 제네릭 타입도 type, interface 둘 다 사용 가능하다. 
type TGState<T> = {
  first: T,
  second: T,
}

interface IGState<T> {
  first: T,
  second: T
}

📌 type과 interface의 결정적 차이

1. interface는 객체 확장 시 유니온 타입의 객체를 확장시킬 수 없다.

type TState = {
  first: number;
}

type TStateOrPop = TState | { population : number };

/* 
  Error: An interface can only extend an object type or intersection   of object types with statically known members.ts
  - 정적인 객체만 확장이 가능하다... ( 유니온 객체는 불가능 )
*/
interface IStateOrPopAndMore extends TStateOrPop {
  more: number;
}

// 가능
type TStateOrPopAndMore = TStateOrPop & {
  more: number;
}

2. 튜플과 배열 타입을 인터페이스로 구현 시 배열 관련 메서드 사용 불가

type TTuple= [number, number];

interface ITuple {
  0: number;
  1: number;
  length: 2;
}

const t1: TTuple = [10, 20];
const t2: ITuple = [10, 20];

// 가능
t1.concat(1);
/*
  Error : Property 'concat' does not exist on type 'ITuple'
  - Interface의 객체에 사용할 속성을 모두 지정해주어야 하는 듯하다. 
*/ 
t2.concat(1);

3. 인터페이스 기존의 인터페이스 타입에서 '보강'이 가능하다.

interface IState {
  name: string;
}

interface IState {
  population: number;
}

// 선언 병합이 가능, state는 name과 population 속성이 있는 객체
const state: IState = {
  name: "Junseung",
  population: 1,
} 


type TState = {
  name: string;
};

/* 
  Error : Duplicate identifier 'TState'
  - 중복 선언 에러
*/
type TState = {
  population: number;
};

📌 프론트개발을 위한 type vs Interface

1. 선언 병합이 가능한 Interface 사용, 어쩌면 매우 심각한 부작용으로 다가올 수 있다.

타입스크립트는 명시적 타이핑 기법이 아닌 구조적 타이핑 기법이다. 즉, 함수의 이름에 따라 타입이 정해지는 것이 아닌, 타입의 객체 key, value 구조에 따라 타입이 정해진다.

이는 타입의 구조가 동일하다면 같은 타입으로 분류되고 이름이 다르더라도 같은 타입으로 사용할 수 있다는 뜻이다.

즉, 타입스크립트에서 타입은 재사용성 또한 고려해야한다는 점이다.

따라서 선언 병합으로 인해 타입이 동적으로 변하게 된다면 타입을 재사용하는 입장에서 심각한 부작용을 낳을 수 있다.

2. Interface는 유니온 연산자의 제한적 사용을 고려해야한다.

앞서 설명한 것처럼 Interface는 유니온 타입을 확장할 수 없다. 하지만 interface의 유니온 타입의 제한적 사용을 고려해야할 만큼에 Interface의 장점은 아직 찾지 못하였다.

👍 결론

위와 같은 이유로 타입스크립트로 코드를 짤 때 타입 선언을 interface가 아닌 type으로 선언하고 있다.

하지만 편향적으로 코드를 짜는 것을 나쁘다고 생각이 들어 interface를 사용하고 좋은 이유도 계속해서 찾고 있다.

P.S 이 글을 보시고 interface로 타입 선언하면서 개발하시는 분이 계시다면 그 이유를 댓글로 남겨주세요!!

참고 자료
이펙티브 타입스크립트 - 타입과 인터페이스 차이점 알기

profile
다른 사람들이 이해하기 쉽게 기록하고 공유하자!!

0개의 댓글