[TypeScript] type과 interface의 차이

이다미·2024년 5월 13일

TypeScript에서 타입을 정의할 때 type 혹은 interface를 사용한다.

이런 상황에서는 type을 쓰고, 저런 상황에서는 interface를 사용하는 것을 보고 각 역할에 대한 의문점이 들었다.

따라서 이번주는 이 2가지의 키워드가 어떤 차이점을 가지는지에 대해 알아보았다.


두 키워드 큰 틀의 차이로는,

interface는 객체 형태만 가능하지만, type은 객체 형태 뿐만 아니라 모든 유형의 타입을 정의할 수 있다.

📚 사용 가능 범위

interface

객체 타입을 설정할 때 사용할 수 있으며, 원시 자료형에는 사용할 수 없다.

interface Person {
  name: string;
  age: number;
  gender: string;
}

interface 이름 expends 원시자료형 {...} // ❌ 그냥 불가능하다!!! ❌

(*원시 자료형 : string, number, boolean, undefined, null)

type

객체 타입을 정의할 때는 물론, 단순한 원시값이나 튜플, 유니언 타입 등 모든 타입에 대하여 선언이 가능하다.

// 원시값
type name = string;
type age = number;
type graduated = boolean;

// 튜플
type Person = [string, number, boolean];

// 유니언
type strNum = string | number;
type gender = "male" | "female";

// 객체형
type Person = {
  name: string;
  age: number;
  phone: string;
}

📚 객체 상속 및 확장

interface

  1. extends 키워드를 이용하여 확장할 수 있다.

    interface Person {
      name: string;
      age: number;
    }
    
    interface User extends Person {
      phone: string;
    }
    
    const admin: User = {
        name: 'admin',
        age: 10,
        phone: '01011112222'
    }
  2. 같은 이름의 interface를 선언하면 자동으로 확장된다. (통과)

    interface Person {
      name: string;
      age: number;
    }
    
    interface Person {
      phone: string;
    }
    
    const admin: Person = {
      name: 'admin',
      age: 10,
      phone: '01011112222'
    }

    → 한 스코프 안에 Person 이라는 인터페이스를 중복으로 정의했음에도 var 키워드처럼 중복 할당을 허용한다.

type

  1. & 기호를 이용하여 확장할 수 있다.

    type Person = {
      name: string;
      age: number;
    }
    
    type User = Person & {
      phone: string;
    }
    
    const admin: User = {
      name: 'admin',
      age: 10,
      phone: '01011112222'
    }
  2. 같은 이름의 type을 선언해도 확장되지 않는다. (오류 발생)

    type Person = {    // ❗️error: 'Person' 식별자가 중복되었습니다.
      name: string;
      age: number;
    }
    
    type Person = {    // ❗️error: 'Person' 식별자가 중복되었습니다.
      phone: string;
    }
    
    const admin: User = {
      name: 'admin',
      age: 10,
      phone: '01011112222'  // ❗️error: 'Person' 형식에 'phone'이 없습니다.
    }

→ 객체를 타입으로 정의하면 동일 스코프에서 동일한 이름의 타입에 중복으로 할당하는 것을 방지해, const 키워드를 사용한 것처럼 동작한다.

📚 그래서 어떻게 사용해야 하는가?

객체 위주로 생각해보면, 어떤 방식으로도 선언이 가능하다.
둘 중 어느 것 하나의 단점이 크다고 할 수도 없고, 각 상황마다 더 편리한 방법이 존재하기 때문이다.

→ 결론적으로 객체 타입을 정의하거나 객체 형식을 확장할 때 interface 가 일반적으로 사용된다고 한다.

interface는 속성 간 충돌을 해결하기 위해 단순한 객체 타입을 만들고, 객체 타입만 허용이 되기 때문에 확장을 하기에도 더 단순하다.

  • interface는 주로 클래스나 객체의 구조를 명시적으로 정의할 때 사용되며, 이러한 목적에 가장 적합하게 나왔다.

반면 type의 경우, 재귀적으로 순회하면서 속성을 머지하기 때문에 일부 충돌이 발생할 수 있다.

  • type은 주로 일반적인 타입 정의에 사용되며, 유니언 타입이나 교차 타입 등을 선언할 때 사용된다.

(다만, TypeScript의 버전이 업데이트되면서 typeinterface 사이의 차이가 점차 축소되고 있다…)

문제가 생기면 컴파일러가 알려주기 때문에 개인 취향에 따라,, 혹은 코드 컨벤션에 따라 작성하면 될 것 같다.


참고 자료
TypeScript: type과 interface는 어떻게 다를까
타입스크립트에서 type 과 interface 더 알아보기
TypeScript - type과 interface의 차이

0개의 댓글