본문으로 바로가기

type vs interface

object typing을 위해서 type alias를 이용할 수도 있고, interface를 이용할 수도 있습니다.

예전에는 interface가 extends를 할 수 있어 더 다형성이 높으므로 interface를 사용하라고 하였는데 사실 type도 가능합니다.

interface Animal { name: string }
interface MyAnimal extends Animal { behavior: string }

type AnimalType = { name: string }
type YourAnimal = AnimalType & { behavior: string } // &를 이용하여 extends 가능

 

사실 interface가 선호되는 이유는 확장성이 아닙니다.

type와 interface의 핵심적인 차이는

"interface 는 같은 이름으로 선언하여 기존 interface에 필드를 추가할 수 있는 반면 type는 재선언할 수 없다"는 것입니다.

type Item = { name: string }
type Item = { owner: string } //Duplicate identifier 'Item'

interface Item { name: string }
interface Item { owner: string } // Item은 {name: string, owner: string}이 됨.

 

union vs intersection

union은 |

intersection은 &

직관적으로 무엇인지 이해할 수 있을 것이다.

typesafe한 동작을 위해 union type을 파라미터로 사용해야 한다면 타입 단언과 같은 Narrowing을 거쳐야 원하는 프로퍼티, 메서드에 접근할 수 있게 된다.

interface IDeveloper {
  name: string;
  skill: string;
}

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

// union의 경우 or이다. IDeveloper 이거나 IPerson이어야 함
function askTo(a: IDeveloper | IPerson) {
  // a.skill과 a.age가 인텔리센스에 안 잡힌다.
  // 공통되는 a.name만 잡힌다.
  // 이는 a가 IDeveloper일수도, IPerson일수도 있기 때문에 typesafe한 동작 방식을 위해 의도된 것.
  console.log(a.name);
}
askTo({ name: "darren", skill: "ts" });

// intersection이므로 IDeveloper 이자 IPerson인 것을 사용해야 한다.
function askFor(b: IDeveloper & IPerson) {
  console.log(b.name);
  console.log(b.skill);
  console.log(b.age);
}

askFor({ name: "darren", skill: "ts", age: 23 });

 

Type Guard에 대해서는 다음 글을 참고해보도록하자!

 

https://darrengwon.tistory.com/915?category=867626 

 

타입 가드 (type guard)

아래의 경우 유니언 타입으로 잡아주었기 때문에 공통적인 프로퍼티만 사용할 수 있습니다. 만약 intersection을 사용하면 정의 자체를 name, age, skill을 전부 넣어줘야 하니 의도한 방식이 아닙니다.

darrengwon.tistory.com

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체