티스토리 뷰

CS/Language

[TypeScript] type vs interface

OpusK 2022. 3. 22. 07:25
반응형

type vs interface

 

타입 스크립트를 사용하다 보면, type (type aliases)과 interface를 사용하게 된다.

이름을 봐서는 분명 서로 간에 차이가 있을 것 같지만, 생김새가 똑같고 실제 사용 방식도 거의 비슷하다.

어느 때 어떤 것을 사용하는 것이 좋을까?

type T = {
  cnt: number;
};

interface T {
  cnt: number;
}

 

아래는 공식 페이지 플레이그라운드에 공개된 예제 코드이다.

제목부터 Types vs Interfaces인데, 이 예제 코드 영어 주석 밑에 한글로 설명을 추가하였으니 코드를 보며 읽어보면 좋을 것 같다.

 

 

TS Playground - An online editor for exploring TypeScript and JavaScript

The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.

www.typescriptlang.org

// There are two main tools to declare the shape of an
// object: interfaces and type aliases.
//
// They are very similar, and for the most common cases
// act the same.
// 여기서도 둘이 매우 유사하고 대부분의 경우에는 동작 또한 동일하다고 이야기 하고 있다.

type BirdType = {
  wings: 2;
};

interface BirdInterface {
  wings: 2;
}

const bird1: BirdType = { wings: 2 };
const bird2: BirdInterface = { wings: 2 };

// Because TypeScript is a structural type system,
// it's possible to intermix their use too.
// 아래에서 보는 것처럼 type으로 선언한 것을 interface 타입에 대입하고 있으며,
// 에러 상황이 아니 정상적인 문법이다. 이것을 intermix 라고 표현한다.

const bird3: BirdInterface = bird1;

// They both support extending other interfaces and types.
// Type aliases do this via intersection types, while
// interfaces have a keyword.
// 둘 모두 아래와 같이 확장 기능을 제공한다.
// 다만, type이 &를 사용한 intersection type(정적으로 알 수 있는 타입)을 통해 확장하는 반면,
// interfaces는 extends 키워드를 사용하면 된다.

type Owl = { nocturnal: true } & BirdType;
type Robin = { nocturnal: false } & BirdInterface;

interface Peacock extends BirdType {
  colourful: true;
  flies: false;
}
interface Chicken extends BirdInterface {
  colourful: false;
  flies: false;
}

let owl: Owl = { wings: 2, nocturnal: true };
let chicken: Chicken = { wings: 2, colourful: false, flies: false };

// That said, we recommend you use interfaces over type
// aliases. Specifically, because you will get better error
// messages. If you hover over the following errors, you can
// see how TypeScript can provide terser and more focused
// messages when working with interfaces like Chicken.
// TS진영에서는 interfaces를 더 사용할 것을 추천하고 있다.
// 에러 메세지를 얻기에 더 좋다고 하는데, 아마 extends의 형태로 확장함으로써,
// JS의 핵심 가치인 프로토타입 객체 형태처럼 사용하여, 보다 자바스크립트스럽게
// 사용할 수 있게 만든 것이 interface인것 같다.
// 참고로, 아래 코드는 둘이 가지고 있는 properties가 다르기 때문에 에러가 난다.

owl = chicken;
chicken = owl;

// One major difference between type aliases vs interfaces
// are that interfaces are open and type aliases are closed.
// This means you can extend an interface by declaring it
// a second time.
// 위의 내용이 syntax적인 차이였다고 하면,
// 여기서 설명하는 내용은 concept가 다르다는 것이다.
// interface는 open되어 있는 반면에 type은 closed 되어있다고 설명하고 있는데,
// 즉, interface는 재선언을 통해 확장이 가능하지만
// type의 경우 static하기 때문에 중복(duplicate)선언으로 처리된다.

interface Kitten {
  purrs: boolean;
}

interface Kitten {
  colour: string;
}

// In the other case a type cannot be changed outside of
// its declaration.
// 중복 선언이 안되는 예시이다 -> 에러 발생

type Puppy = {
  color: string;
};

type Puppy = {
  toys: number;
};

// Depending on your goals, this difference could be a
// positive or a negative. However for publicly exposed
// types, it's a better call to make them an interface.

// One of the best resources for seeing all of the edge
// cases around types vs interfaces, this stack overflow
// thread is a good place to start:

// https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types/52682220#52682220

 

정리

  1. 대부분의 용례는 똑같다
  2. 상호 간의 intermix (상호 대입)이 가능하다 ( 구조적-structural-으로 동일하다면 )
  3. type은 & (AND, intersection type)을 사용하여 확장하는 반면에, interface는 extends를 사용한다.
  4. interface는 재선언을 통한 확장이 가능하지만, type은 중복 선언 오류를 던진다.
  5. TS 공식입장은 interface를 더 추천한다는 것이다.
  6. 특히 public 하게 공개되어야 하는 경우는 interface를 사용하는 것을 추천한다.
  7. 반면에, union이나 tuple 같은 타입은 interface로써는 할 수 없으니 이 경우는 type을 사용해야 한다.
  8. 정리하면, 둘의 트레이 오프가 분명하며 edge case 또한 다르기 때문에 상황에 맞게 쓰는 것이 좋다.

마지막 8번에 대한 이야기를 좀 더 하자면,

type aliases는 static 특성을 가지고 있다. 즉, 중복 선언을 통한 의도치 않은 확장을 방지하고 싶거나 정적으로 구조가 결정되어야 하는 경우는 type aliases를 사용하는 것이 바람직하다는 것이다.

물론, 프로토타입을 중심으로 다이내믹한 특성을 추구하는 JavaScript 철학에는 interface가 더 알맞다. 그래서 이들도 interface를 더 추천하는 것일 것이다.

다만, TypeScript 자체가 JavaScript의 "타입에 대한 문제"를 보완하기 위해 나온 JS의 슈퍼셋이니 만큼, 이러한 type aliases도 적재적소에 사용하는 것이 바람직할 것이다. (의미 없는 것이었다면, 진작 deprecated 처리했을 것이다)

 

 

더 보면 좋을 자료

 

TypeScript: The Difference Between Interface and Type

Once we start exploring TypeScript, we start using interfaces and types without really understanding...

dev.to

 

반응형
댓글