[TypeScript] type과 interface의 차이

흩날리는추억·2024년 7월 10일

✔️ 들어가기 전

6월 중순부터 개인적인 사정들이 있어서 진행하고 있던 movie app를 방치하고 있었다. 분명 조금씩이라도 진행할 여유가 있었지만... 내 스스로가 나태했던 걸 반성하며 다시 시작하기로 했습니다. 그 시작을 TypeScript의 type과 interface에 대해 학습하고 이를 movie app에 적용시켜보려 합니다.

❓ type과 interface?

타입스크립트(TypeScript)에서 type과 interface는 둘 다 객체의 형태를 정의하는 데 사용되지만, 각각의 특징과 사용 용도가 조금씩 다릅니다.

📢 선언 방식

type의 경우 '='가 있지만 interface는 없다.

// type
type User = {
  name: string;
  age: number;
};

// interface
interface User {
  name: string;
  age: number;
}

➕ 확장(Extension)

type의 경우 '&'를 사용하여 확장

type Person = {
  name: string;
};

type User = Person & {
  age: number;
};

interface의 경우 Java와 같은 언어에서도 사용하는 'extends'를 사용하여 확장

interface Person {
  name: string;
}

interface User extends Person {
  age: number;
}

🙏 병합(Merging)

Interface는 동일한 이름을 가진 인터페이스들이 선언되면 자동으로 병합(선언 병합)

interface User {
  name: string;
}

interface User {
  age: number;
}

// 결과적으로 User는 { name: string; age: number; }가 됩니다.

Type은 동일한 이름을 가진 타입을 여러 번 선언할 수 없다.

type User = {
  name: string;
};

type User = {
  age: number;
};

// 오류 발생: 동일한 이름의 타입을 다시 선언할 수 없습니다.

🔍 type만의 특징

// 기본 타입(숫자, 문자열 등)에 별칭
type Name = string;
type Age = number;

// 유니온(|)과 인터섹션(&) 타입을 사용하여 새로운 타입을 정의
type NameOrAge = { name: string } | { age: number };
type NameAndAge = { name: string } & { age: number };

// 교차 타입
type Employee = Person & {
  employeeId: ID;
};

// 제네릭 사용 가능
type GenericResponse<T> = {
  status: number;
  payload: T;
};

// 튜플 타입
type StringNumberPair = [string, number];
let pair: StringNumberPair = ["hello", 42];

// 배열 타입
type StringArray = string[];
let strings: StringArray = ["one", "two", "three"];

🔍 interface만의 특징

// 선택적 프로퍼티
interface Product {
  name: string;
  price?: number;
}

// 클래스 구현
class Developer implements Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

👀 type과 interface 어떤 상황에서 사용할까?

  • interface는 객체의 구조를 정의하고 확장성이 필요한 경우 사용
    예를 들어, 여러 모듈에서 동일한 객체 구조를 확장하거나 병합해야 하는 경우

  • type은 유연한 타입 정의가 필요하거나, 유니온 타입, 튜플 등을 정의해야 할 때 사용

🚀 프로젝트에 적용해보자!

현재 movie app의 경우 Http get 통신을 통해 받아온 객체를 활용하여 UI에 표출하는게 주된 프로젝트이다. 유연한 타입의 정의가 필요하거나 튜플과 같은 것을 사용할 필요는 없어 기존에 쓰던 interface를 사용하기로 했다.

다만 코드를 살펴보니 단순히 interface를 사용해서 받아오는 객체마다 객체 타입을 지정해 사용했기 때문에 중복된 부분이 많아 보여 이를 수정하기로 했다.

👀 수정 전

🍿 수정 후

공통된 부분을 확인하여 객체 타입을 정의하였고 이를 토대로 interface의 확장 기능을 통해 코드를 수정했다. 중복된 부분이 해소되어 코드의 양이 줄어들었고, 이를 통해 가독성이 높아진걸 체감할 수 있었다.

✏️ 마무리

type과 interface의 차이점을 제대로 알지 못한체 계속 사용했었는데 그때마다 찜찜한 기분을 떨친 순 없었다. 이번 학습을 통해 이제는 그런 부분이 해소되었다 생각하니 기분이 홀가분하다. 하지만 아직 제대로 학습했다고 생각하진 않는다. interface의 클래스를 활용한 사용을 해본 적이 없고, type의 경우는 실제 프로젝트에 적용해 본 적이 없기 때문이다.

위 문제에 프로젝트에 적용할 부분이 없거나 필요성이 없다고 판단된다면, 간단한 예제를 찾아서 학습할 생각이다.

🙏 글 작성에 도움받은 목록

wlwl99님의 벨로그
youngju-js님의 티스토리

profile
걱정보다 생각을 하고 싶은 사람

0개의 댓글