HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🚀
개발 노트
/
🎾
타입스크립트
/
🎁
Type vs Interface (by 엘리)
🎁

Type vs Interface (by 엘리)

 

기술 측면

공통점

  • 객체의 타입을 정의하는 데 사용할 수 있다.
  • 클래스를 구현(implements)하는 데 사용할 수 있다.
  • 확장(Extends)할 수 있다.
type은 원래 확장이 불가능했으나, 최근 버전에서 가능해졌다.

차이점

  • interface만 병합(merge)할 수 있다. (선언적 확장)
  • Type만 computed properties를 사용할 수 있다. (계산된 프로퍼티)
 
  • interface는 객체에만 사용이 가능하다. type은 객체 외에도 원시값, 유니온 타입, 튜플 등에도 사용할 수 있다.
 

개념 측면

Interface

정의: “어떤 것의 스펙, 규격 사항”
클래스, 라이브러리 등에 대한 규격을 정의하는 경우 적합하다.
어떤 것을 구현하기 위해 참고하는 문서로 생각할 수 있다.
 
“이 클래스는 이 인터페이스를 구현한다 (O)”
“이 클래스는 이 타입을 구현한다 (❓)”

Type

정의: “어떤 데이터의 타입(형태)”
데이터의 형태를 묘사한다. 데이터를 담을 목적인 경우 적합하다.
 
“이 컴포넌트에 전달할 수 있는 Props 타입은 이 Type이다 (O)”
“이 컴포넌트에 전달할 수 있는 Props 타입은 이 interface이다(❓)”
 

결론

  • 대부분의 경우 타입과 인터페이스는 유사하다.
    • 코드베이스에서 일관성을 유지하는 것이 더 중요하다.
  • 복잡한 타입을 다룰 때에는 type을 사용하는 것이 좋다. (계산된 프로퍼티)
  • 컴포넌트의 props와 state에 대한 타입을 선언할 때 Type을 사용하는 것이 적합하다. 의미적으로 적합하며, 더 제한적이기 때문에 유리하다.
interface를 사용해도 괜찮다. 일관성을 유지하는 것이 더 중요하다.
  • 클래스, 라이브러리를 제작할 때는 인터페이스를 사용하라. 의미적으로 적합하며, 상속을 통해 확장이 필요할 때 더 유리하다.
  • 서버에서 받아오는 API 응답은 type으로 정의하는 것이 의미상 적절하다.
    • 클라이언트와 서버가 주고 받는 데이터의 형태를 정의하는 것이기 때문이다. 이
       

이펙티브 타입스크립트

  • 대부분의 경우에는 타입을 사용해도 되고 인터페이스를 사용해도 됩니다. 그러나 타입과 인터페이스 사이에 존재하는 차이를 분명하게 알고, 같은 상황에서는 동일한 방법으로 명명된 타입을 정의해 일관성을 유지해야 합니다.
  • 복잡한 타입이라면 고민할 것도 없이 타입을 사용하면 됩니다. 그러나 타입과 인터페이스, 두 가지 방법으로 모두 표현할 수 있는 간단한 객체 타입이라면 일관성과 보강의 관점에서 고려해 봐야 합니다. 일관되게 인터페이스를 사용하는 코드베이스에서 작업하고 있다면 인터페이스를 사용하고, 일관되게 타입을 사용 중이라면 타입을 사용하면 됩니다.
  • 아직 스타일이 확립되지 않은 프로젝트라면, 향후에 보강의 가능성이 있을지 생각해 봐야 합니다. 어떤 API에 대한 타입 선언을 작성해야 한다면 인터페이스를 사용하는 게 좋습니다. API가 변경될 때 사용자가 인터페이스를 통해 새로운 필드를 병합할 수 있어 유용하기 때문입니다. 그러나 프로젝트 내부적으로 사용되는 타입에 선언 병합이 발생하는 것은 잘못된 설계입니다. 따라서 이럴 때는 타입을 사용해야 합니다.
 
// 타입 type PositionType = { x: number; y: number; } // 인터페이스 interface PositionInterface { x: number; y: number; }
class Pos1 implements PositionType { x: 1; y: 2; } class Pos2 implements PositionInterface { x: 1; y: 2; }
// type은 인터섹션 연산자로 확장 type ZPositionType = PositionType & { z: number }; // interface는 상속을 통해 확장 (또는 선언적 병합) interface ZPositionInterface extends PositionInterface { z: number; };
interface Box { height: number; width: number; } interface Box { scale: number; } let box: Box = {height: 5, width: 6, scale: 10};
type Person = { name: string, age: number } type Name = Person['name']; // string
interface FooInterface { value: string } type FooType = { value: string } type FooOnlyString = string type FooTypeNumber = number