타입과 인터페이스 차이점 알기

이재철·2023년 4월 4일
0

TypeScript

목록 보기
7/11
post-thumbnail

명명된 타입을 정의하는 방법은 두가지가 있습니다.

type Tstate = {
  name: string;
  capital: string;
}

interface IState {
  name: string;
  capital: string;
}

대부분의 경우는 타입을 사용해도 되고 인터페이스를 사용해도 됩니다.
같은 상황에서는 동일한 방법으로 명명된타입을 정의해 일관성을 유지해야합니다.

타입을 I(인터페이스) 또는 T(타입)로 시작해 어떤 형태로 정의되었는지 나타냈지만 지양해야 할 스타일입니다. (C# 관례)

타입과 인터페이스의 공통점

추가 속성과 함께 할당하면 오류 발생합니다.

const wyoming: TState = {
  name: 'Wyoming',
  capital: 'Cheyenne',
  population:5 50000
};
// ..형식은 'TState' 형식에 할당할 수 없습니다. 
// 개체 리터럴은 알려진 속성만 지정할 수 있으며, 
// TState 형식에는 population이 없습니다.

인덱스 시그니처 인터페이스, 타입 모두 사용 가능합니다.

type TDict = { [key: string]: string};

interface IDict {
  [key: string]: string;
}

함수타입을 인터페이스나 타입으로 지정할 수 있습니다.

type TFn = (x: number) => string;
interface IFn {
  (x: number) :string;
}

type TFnWithProperties = {
  (x: number): number;
  prop: string;
}
interface IFnWithProperties {
  (x: number): number;
  prop: string;
}

인터페이스는 타입을 확장할 수 있으며, 타입은 인터페이스를 확장할 수 있습니다.

interface IStateWithPop extends TState {
	population: number;
}

type TStateWithPop = IState & { population: number }

🚨 인터페이스는 유니온 타입 같은 복잡한 타입을 확장하지는 못한다는 것입니다.
➡ 복잡한 타입을 확장하고 싶다면 타입과 &를 사용해야 합니다.

클래스 구현 시 사용가능합니다.

class StateT implements TState {
  name: string = '';
  capital: string = '';
}

class StateI implements IState {
  name: string = '';
  capital: string = '';
}

타입과 인터페이스의 차이점

타입

유니온 타입은 있지만 유니온 인터페이스라는 개념은 없습니다.

type AorB = 'a' | 'b';

인터페이스는 타입을 확장할 수 있지만, 유니온은 할 수 없습니다.
✅ 유니온 타입을 확장하는 게 필요할 때가 있습니다.

type Input = {/* ... */};
type Output = {/* ... */};
interface VariableMap {
  [name: string]: Input | Output;
}

이 타입은 인터페이스로 표현할 수 없습니다. type 키워드는 일반적으로 interface 보다 쓰임새가 많습니다.

type NamedVariable = (Input | Output) & {name: string}

type 키워드는 유니온이 될 수 있고, 매핑된 타입 또는 조건부 타입 같은 고급 기능에 활용 될 수 있습니다.

튜플, 배열 간결한 표현

튜플을 인터페이스로 구현해도, 튜플에서 사용할 수 있는 const 같은 매서드를 사용할 수 없기 때문에, 튜플은 type으로 구현하는게 좋습니다.

type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];

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

인터페이스

보강(augment) 가능합니다.
➡ 속성을 확장하는 것을 선언 병합이라고 합니다.

interface IState {
  name: string;
  capital: string;
}
interface IState {
  population: number;
}
const wyoming: IState = {
  name: 'Wyoming',
  capital: 'Cheyenne',
  population: 500_000
};

✅ 복잡한 타입이라면 타입 별칭을 사용하면 됩니다. 그러나 타입과 인터페이스, 두 가지 방법으로 모두 표현 할 수 있는 간단한 객체 타입이라면 일관성과 보강의 관점에서 고려해 봐야 합니다.
아직 스타일이 확립되지 않은 프로젝트라면, 향후 보강의 가능성이 있는지 확인이 필요합니다.

  • 어떤 API에 대한 타입 선언을 작성해야 한다면 인터페이스를 사용하는 게 좋습니다.
    ➡ API가 변경될 때 사용자가 인터페이스를 통해 새로운 필드를 병합할 수 있어 유용합니다.

  • 프로젝트 내부적으로 사용되는 타입에 선언 병합이 발생하는 것은 잘못된 설계입니다.
    ➡ 이런 경우 타입을 사용해야합니다.

profile
혼신의 힘을 다하다 🤷‍♂️

0개의 댓글