[TS] type과 interface의 차이점

jiny·2025년 1월 30일

기술 면접

목록 보기
49/78

🗣️ 타입스크립트에서 typeinterface의 차이점은 무엇인가요?

  • 의도: 타입스크립트 환경에서 본인의 습관을 파악하려는 질문

  • 팁: 비교를 통해 간결하게 전달하면 좋다.

  • 나의 답안

    typeinterface는 모두 객체의 구조를 정의하기 위한 타입 정의 방법이지만, 용도와 확장 방식에서 차이가 있습니다.

    먼저 interface객체의 형태를 정의하고, 다른 인터페이스를 상속(extends) 해서 확장할 수 있습니다.
    즉, 객체 중심적이고 확장성에 강한 구조를 만들 때 유용합니다.

    반면 type은 단순히 객체뿐 아니라 유니온 타입, 교차 타입, 프리미티브 타입 등 더 다양한 타입 조합을 표현할 수 있습니다.
    예를 들어, 문자열 리터럴이나 유니온처럼 좀 더 복잡한 타입 연산이 필요할 때type을 사용하는 게 적합합니다.

    정리하자면, interface확장을 위한 설계, type타입 조합과 유연한 표현에 강점이 있다고 말할 수 있습니다.

  • 주어진 답안 (모범 답안)

    둘 다 커스텀 타입을 정의하는 데에 사용되지만, 대표적인 차이로는 interface는 객체의 타입 정의에만 쓴다는 점입니다.
    그 외 차이점으로는 잠재적인 오류를 피할 수 있다는 점이 있습니다.

    interface같은 이름의 interface를 여러 번 선언하면 자동으로 합쳐져 오류를 피할 수 있지만, type의 경우에는 이런 병합이 불가능해 오류가 나게 됩니다.
    그래서 보통 interface를 기본 값으로서 쓰는 편입니다.

    다만 type을 활용할 때는 따로 있는데, 바로 타입 앨리어싱이나 복잡한 타입을 만들 때 사용하곤 합니다.


📝 개념 정리

🌟 typeinterface의 공통점

typeinterface 모두 타입스크립트에서 타입을 정의하는 기능을 한다.
둘 다 객체의 구조를 정의할 때 사용되며, function, array, class 등 다양한 타입을 선언할 수 있다.

  • 공통점 요약
    • 객체의 구조를 정의할 수 있다.
    • 함수, 배열, 클래스의 타입을 지정할 수 있다.
    • 확장(extends, & 연산자)을 지원한다.

🌟 typeinterface의 주요 차이점

typeinterface는 여러 차이점이 존재하며, 용도에 따라 적절한 선택이 필요하다.

구분typeinterface
선언 방식type 키워드 사용interface 키워드 사용
확장 방식&(Intersection) 사용extends 키워드 사용
중복 선언불가능 (재선언 불가)가능 (자동 병합)
사용 가능 범위원시 타입, tuple, union, intersection 등 다양하게 사용 가능객체 타입만 정의 가능
성능컴파일 시 더 빠름 (최적화가 잘됨)상대적으로 느림
Mapped Type 지원지원함제한적임
클래스에서 구현(implements)가능함가능함

🌟 typeinterface의 차이를 코드 예제로 이해하기

  1. 기본적인 사용법

    • type 사용

      type User = {
        name: string;
        age: number;
      };
      
      const user: User = { name: "Alice", age: 25 };
    • interface 사용

      interface user {
        name: string;
        age: number;
      }
      
      const user: User = { name: "Alice", age: 25 };
    • 결론: 차이점 없음 → 객체의 구조를 정의하는 데에는 typeinterface 모두 사용 가능하다.

  1. 확장(Extending)

    • type&(Intersection) 사용

      type Person = { name: string };
      type Employee = Person & { company: string };
      
      const emp: Employee = { name: "Bob", company: "Google" };
    • interfaceextends 사용

      interface Person {
        name: string;
      }
      
      interface Employee extends Person {
        company: string;
      }
      
      const emp: Employee = { name: "Bob", company: "Google" };
    • 결론

      • 둘 다 확장 가능하지만, type& 연산자를 사용하고, interfaceextends 키워드를 사용한다.
      • interface는 여러 개 확장이 가능하다. (interface A extends B, C {})
  1. 중복 선언 가능 여부

    • type은 중복 선언 불가능

      type Animal = {
        name: string;
      };
      
      type Animal = {
        age: number;
      }; // [에러] Amimal이 이미 정의됨
    • interface는 중복 선언이 가능하고, 자동으로 병합됨(Declaration Merging)

      interface Animal {
        name: string;
      }
      
      interface Animal {
        age: number;
      }
      
      // 자동 병합됨
      const dog: Animal = { name: "Rex", age: 3 };
    • 결론: interface는 중복 선언 시 자동으로 병합되지만, type은 불가능

  1. 유니온(|)과 교차(&) 타입 지원
    • type은 유니온(|)과 교차(&) 타입을 사용할 수 있음
      type StringOrNumber = string | number; // 유니온 타입
      type Dog = { bark: () => void };
      type Cat = { meow: () => void };
      type Pet = Dog & Cat; // 교차 타입
    • interface는 유니온 타입을 사용할 수 없음
      interface StringOrNumber = string | number; // [에러] 오류 발생
    • 결론: 유니온 타입과 교차 타입을 사용할 수 있는 것은 type만 가능
  1. Mapped Type 지원 여부

    • type은 Mapped Type을 지원함

      type ReadOnly<T> = {
        readonly [K in keyof T]: T[K];
      };
      
      type User = { name: string; age: number };
      type ReadOnlyUser = ReadOnly<User>; // 모든 속성이 readonly가 됨
      • [K in keyof T] : T 객체 타입의 키(keyof T)를 반복(iterate)하면서 매핑
      • T[K] : 해당 키의 값을 그대로 가져옴
    • interface는 Mapped Type을 지원하지 않음

      interface ReadOnly<T> {
        readonly [K in keyof T]: T[K]; // [에러] 오류 발생
      }
    • 결론: Mapped Type을 사용할 때는 type을 써야 함

  1. 클래스에서 implements로 사용

    • typeimplements에서 사용

      type Animal = {
        makeSound(): void;
      };
      
      class Dog implements Animal {
        makeSound() {
          console.log("Woof!");
        }
      }
      
      const dog = new Dog();
      dog.makeSound(); // "Woof!"
    • interfaceimplements에서 사용

      interface Animal {
        makeSound(): void;
      }
      
      class Dog implements Animal {
        makeSound() {
          console.log("Woof!");
        }
      }
      
      const dog = new Dog();
      dog.makeSound(); // "Woof!"
    • 결론: 클래스에서 implements를 사용할 때는 interface를 쓰는 것이 일반적이지만, type도 사용 가능


🌟 언제 type을 쓰고 언제 interface를 쓸까?

  • type을 사용할 때
    • 유니온(|) 또는 교차(&) 타입이 필요할 때
    • 함수 타입을 정의할 때
    • Mapped Type이 필요할 때
    • 원시 타입(string, number 등)과 조합해야 할 때
  • interface를 사용할 때
    • 객체의 구조를 정의할 때 (OOP 스타일)
    • 확장이 필요한 경우 (extends 사용)
    • 라이브러리나 API에서 타입을 정의할 때 (자동 병합 지원)
    • 클래스에서 implements를 사용할 때

🌟 결론

  • type유연한 타입 시스템, interface객체 중심(OOP) 스타일에서 더 강력한 기능을 제공한다.
  • 유니온, 교차 타입이 필요하면 type이 더 적합하고, 재사용성과 확장성을 고려하면 interface가 더 적합하다.
  • 결론적으로, 유연한 타입 조작이 필요하면 type을 활용하고, 단순한 객체 구조interface를 사용하자.

0개의 댓글