320x100
320x100

interface

- 객체 및 함수 타입 (Objects / Function Types)

// 인터페이스를 사용할 때, 같은 이름의 인터페이스는 자동 병합된다.
interface PrintName {
	(name: string): void;
}

interface PrintName {
	(name: number): void;
}

// ok
const printName: PrintName = (name: number | string) => {
	console.log('name: ', name);
};

: 객체 및 함수 타입을 지원

: 같은 인터페이스를 여러번 선언할 수 있으며, 이들은 자동으로 병합됨

{
  interface Parent {
    printName: (name: number) => void;
  }

  interface Child extends Parent {
    // ✅
    printName: (name: string | number) => void;
  }
  
  interface Window {
      title: string
  }

  interface Window {
    ts: TypeScriptAPI
  }
}

: 인터페이스를 상속할 때 서브 타입은 슈퍼 타입과 충돌할 수 없고, 오직 확장만 가능

: extends를 통해 상속

: 객체에 대해 정의할때 성능적으로 유리

 

 

 

 

 

 

Type

- 원시 타입 (Primitive Types)

{
  type CustomString = string;
  const str: CustomString = '';
}

: 새로운 타입을 정의하는 것이 아니기 때문에 type alias로 불림

 

 

-  유니온 타입 (Union Types)

{
  type Fruit = 'apple' | 'lemon';
  type Vegetable = 'potato' | 'tomato';

  // 'apple' | 'lemon' | 'potato' | 'tomato'
  type Food = Fruit | Vegetable;
  const apple: Food = 'apple';
}

: 타입에서만 지원

 

- 튜플 타입 (Tuple Types)

{
  type Animal = [name: string, age: number];
  const cat: Animal = ['', 1];
}

: 타입에서만 지원

 

- 객체 및 함수 타입 (Objects / Function Types)

{
  // 타입을 사용할 때, 그것은 유일 해야하고, 오직 &를 사용해야만 병합 가능하다.
  type PrintName = ((name: string) => void) & ((name: number) => void);

  // ✅
  const printName: PrintName = (name: number | string) => {
    console.log('name: ', name);
  };
}

: 객체 및 함수 타입을 지원. 여러 번 선언 가능한 인터페이스와 달리 유니크 해야하기 때문에 병합되지 않는다

: & (insertion)을 통해 상속의 개념을 구현할 수 있다

{
  type Parent = {
    printName: (name: number) => void;
  };

  type Child = Parent & {
    // 여기서 두 printName은 intersection 된다.
    // 이것은 `(name: number | string) => void`과 같다.
    printName: (name: string) => void;
  };

  const test: Child = {
    printName: (name: number | string) => {
      console.log('name: ', name);
    },
  };

  test.printName(1);
  test.printName('1');
}

 

- 매핑된 객체 타입 (Mapped Object Types)

type Vegetable = 'potato' | 'tomato';

{
  type VegetableOption = {
    [Property in Vegetable]: boolean;
  };

  const option: VegetableOption = {
    potato: true,
    tomato: false,
  };

  // "potato" | "tomato"
  type VegetableAlias = keyof VegetableOption;
}

: 타입으로만 정의 가능

 

- 알려지지 않은 타입 (Unknown Types)

{
  const potato = { name: 'potato', weight: 1 };

  // type Vegetable = {
  // name: string;
  // weight: number;
  // }
  type Vegetable = typeof potato;

  const tomato: Vegetable = {
    name: 'tomato',
    weight: 2,
  };
}

: 타입으로만 가능

: typeof를 통해 타입을 확인 할 수 있음

 

 

 

 

요약

: 타입은 인터페이스의 대부분의 기능을 커버하나, 타입은 확장할 수 없고 인터페이스는 항상 확장 가능하다

 

- 차이점 요약

: 타입은 새로운 속성을 추가하기 위해 같은 이름으로 선언할 수 없음 (유니크 해야하기 때문)

: 인터페이스는 선언적 확장이 가능

: 인터페이스는 객체 및 함수 타입에 대해서만 사용 가능

interface Window {
  title: string
}

interface Window {
  ts: TypeScriptAPI
}

// 같은 interface 명으로 Window를 다시 만든다면, 자동으로 확장이 된다.

const src = 'const a = "Hello World"'
window.ts.transpileModule(src, {})

type Window = {
  title: string
}

type Window = {
  ts: TypeScriptAPI
}

// Error: Duplicate identifier 'Window'.
// 타입은 안된다.

 

- 타입을 사용해야 하는 경우

: 원시 / 튜플 / 함수 / 유니온 / 매핑된 타입을 정의 할 경우

 

- 인터페이스를 사용해야 하는 경우

: 선언 병합의 이점을 활용해야하는 경우

: 객체 타입을 정의하거나, 타입을 사용할 필요 없을 경우

 

 

 

 

 

 

 

 

Reference

 

[Typescript] 타입(Type)과 인터페이스(Interface)의 차이점

타입스크립트에서 타입(Type)과 인터페이스(Interface)는 유사한 점이 매우 많고, 여러 경우에 자유롭게 혼용되어 사용 가능하다. 그러나 둘 사이에는 차이와 한계가 분명히 존재한다. 원시 타입(Prim

ykss.netlify.app

 

타입스크립트 type과 interface의 공통점과 차이점

타입스크립트의 type과 interface의 차이점을 찾아보던 중, 몇 가지 잘못된 사실들을 보면서 진짜로 둘의 차이점이 무엇인지 정리하기 위해서 포스팅한다. (물론 이것도 시간이 지나면 (2021년 3월 기

yceffort.kr

 

300x250
728x90