페블_
반짝이는 시냅스
페블_
전체 방문자
오늘
어제
  • 전체글 보기 (96)
    • QA (0)
    • 프로젝트 회고 (4)
    • 프로젝트 과정 기록 (12)
    • UI 구현 연구일지 (8)
    • Front-end (31)
      • Javascript (7)
      • CSS (10)
      • React (5)
      • Typescript (3)
      • Nextjs (3)
      • 스타일링 라이브러리 (3)
    • Back-end (0)
      • Express (0)
      • DB (0)
    • CS (0)
      • 자료구조 & 알고리즘 (0)
    • CI&CD (1)
    • 툴 사용법 (4)
      • Git (1)
      • Library&패키지 (2)
      • 기타 개발관련 (1)
    • 알고리즘 이론 & 풀이 (36)
      • 백준(BOJ) (14)
      • 프로그래머스 (22)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 캐러셀
  • 파이썬
  • 선형대수학
  • storybook
  • 알고리즘
  • emotion
  • 토이프로젝트
  • UI 컴포넌트
  • 개발블로그_시작
  • 생각
  • 시리즈_표지
  • react
  • 백준
  • JS
  • chartjs
  • Python
  • eslint
  • TypeScript

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
페블_
Front-end/Typescript

[Typescript] interface vs type

Front-end/Typescript

[Typescript] interface vs type

2023. 5. 29. 21:10

Interface와 Type Alias

일반적으로 object 타입에 대해 타입 선언을 할 때에는 둘에 별 차이가 없다.

 

선언 예시

interface Cat {
  name: string;
  age: number;
}

type Cat = {
  name: string;
  age: number;
}

// 사용은 둘 다 똑같다
const kitty: Cat = {
  name: 'Kitty',
  age: 5
}

 

다만 공식 문서의 type alias와 interface 항목을 보면 다음과 같이 정의되어 있다.

 

type alias

  • A type alias is exactly that - a name for any type.
  • 변수 옆에 콜론(:)으로 직접 타입을 지정하던 것을 여러번 재사용하고 별칭을 지어주기 위한 목적으로 만들어졌다.

interface

  • An interface declaration is another way to name an object type
  • object 타입을 정의하기 위한 방법이다.

 

type alias는 타입에 별칭을 붙여주는 것이다. 그렇기 때문에 type alias는 object 외의 원시 타입들도 선언이 가능하다.

// 원시 타입 지정 가능 (boolean, number, string 등)
type Name = string;

// 유니온 타입(or) 혹은 인터섹션 타입(and) 지정 가능
type BtnColor = 'red' | 'green';

 

Interface와 Type Alias 차이점

둘다 확장 가능, 하지만 Interface는 제약이 많다.

interface

  • interface는 extends 키워드로 확장할 수 있다.
  • 쉼표(,)로 다중 확장이 가능하다. type alias에서 &로 새로운 타입을 정의하는 것에 대응되는 개념이다. 하지만 약간의 제약이 있다.
    -> 만약 extends 해서 만들어지는 interface에 슈퍼 타입과 같은 속성이 존재한다면, 그 속성은 슈퍼타입의 것보다 범위가 작거나 같아야 한다.
// Case 1
interface Foo {
  a: string;
}

// 에러
interface Bar extends Foo {
  a: boolean;
  b: number[];
}


// Case 2
interface Foo {
  a: string | boolean;
}

// OK
interface Bar extends Foo {
  a: boolean;
  b: number[];
}

다중상속 - Case 1에서 결과물은 Foo와 Bar의 교집합인 number[]일 줄 알았는데 에러가 발생한다. 다중상속은 같은 속성이 있다면 타입을 갖게 맞춰야 한다.

/* Case 1 */
interface Foo {
  a: (string | number)[]
}

interface Bar {
  a: number[]
}

// 에러
interface MultipleExtends extends Foo, Bar {}

/* Case 2 */
interface Foo {
  a: number[]
}

interface Bar {
  a: number[]
}

// OK
interface MultipleExtends extends Foo, Bar {}

 

type alias - intersection type

  • type alias는 & 를 통해 확장할 수 있다.
  • 그리고 같은 속성에 대해 서로 타입이 다른 경우, 인터섹션 한 결과는 둘을 And한 것과 같다.
  • 하지만 string이면서 동시에 number인 타입이 존재 할 수 없듯이, never (불가능한 값)이 되버린다. 사실상 interface였다면 에러가 발생했을 텐데 인터섹션 타입을 정의할 당시에는 에러가 뜨지 않으므로 주의해야 한다.
    클래스를 implements 할 시점에서야 never 타입이라고 에러가 뜬다.
interface Foo {
  a: string
}

interface Bar {
  a: number
}

type Intersection = Foo & Bar

// Intersection 결과
{
  a: string & number
}

 

중복 선언 가능 여부

interface - 가능

  • Interface를 여러 번 선언하면 마치 모두 합한 것처럼 동작한다. 프로퍼티는 중복으로 존재해도 되지만, 타입이 같아야 한다.
  • 이를 선언 병합이라고 한다.
interface Dog {
  name: string;
}

interface Dog {
  name: string;
  age: number;
}

// 최종적으로 이것처럼 동작한다.
interface Dog {
  name: string;
  age: number;
}

type alias - 불가

type Dog = {
  name: string;
}

type Dog = {
  name: string;
  age: number;
}

// 에러 발생

 

따라서 추가로 interface를 선언해 타입을 확장할 일이 많은 경우(라이브러리, API)의 타입은 interface로 선언하는 것이 좋다. type alias를 이용한 &나 | 연산이 꼭 필요할 때를 제외하고는 웬만하면 interface로 선언하자.

 

Interface와 Type Alias 공통점

둘 다 extends, implements 할 때 사용할 수 있다.

둘 다 interface를 extends 할 때, 혹은 class를 implements 할 때 사용할 수 있다.

다만 제한이 있는데 바로 '정적 타입일 것'

일반적인 object 타입이나 인터섹션 타입이면 문제가 없지만,

합 타입(유니온 타입)이면 에러가 발생한다.

 

(1) 일반적인 타입 정의인 경우

interface Animal {
  name: string;
  age: number;
  legs: number;
}

type Animal = {
  name: string;
  age: number;
  legs: number;
}
// interface로 정의한 것과 type으로 정의한 것 둘 중 무엇을 사용해도 상관 없다

class Cat implements Animal {
  // ...
}

 

(2) 합 타입인 경우

type Animal = {
  name: string;
  age: number;
  legs: number;
}

type Cat = {
  tail: boolean;
}

type Kitty = Animal | Cat;

// Error 발생!
class MyKitty implements Kitty {
  // ...
}

// Error 발생!
interface PinkKitty extends Kitty {}

 

(3) 곱 타입인 경우 - 정적 타입이라 모양을 알 수 있어 괜찮다.

type Kitty = Animal & Cat;

class MyKitty implements Kitty {
  // ...
}

 

결론

  1. 인터섹션(And), 유니온(Or)로 새로운 타입을 만들 때, 튜플 타입을 정의할 때는 type alias를 쓰자. 단, And 되는 타입은 은 말이 되는지 주의깊게 보자.
  2. 확장성이 중요한 경우 interface로 타입 정의를 하자.

And, Or 타입 연산, tuple은 type alias로! 그 외의 경우는 interface로!

 

Reference

 

Type vs Interface, 언제 어떻게?

TypeScript에서 Type Alias와 Interface의 차이를 알아보기

medium.com

 

 

typescript에서의 다중 상속

우리 다중 상속하게 해주세요 🙏

velog.io

 

'Front-end > Typescript' 카테고리의 다른 글

[Typescript] React에서 type, interface는 어디에 정의하는게 좋을까?  (0) 2023.06.16
[Typescript] 이미 존재하는 CRA에 Typescript 추가하기  (0) 2023.06.02
  • Interface와 Type Alias
  • Interface와 Type Alias 차이점
  • 둘다 확장 가능, 하지만 Interface는 제약이 많다.
  • 중복 선언 가능 여부
  • Interface와 Type Alias 공통점
  • 둘 다 extends, implements 할 때 사용할 수 있다.
  • 결론
  • Reference
'Front-end/Typescript' 카테고리의 다른 글
  • [Typescript] React에서 type, interface는 어디에 정의하는게 좋을까?
  • [Typescript] 이미 존재하는 CRA에 Typescript 추가하기
페블_
페블_

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.