프론트 개발자를 위한 여정

모든 영역을 안내하는 개발자

Frontend

[TypeScript]의 interface와 type 차이, 왜 헷갈릴까? 정확히 알아보자!

ji-frontdev 2024. 12. 7. 19:52
반응형

TypeScript에서 객체의 타입을 정의할 때는 interface와 type 두 가지를 사용할 수 있습니다. 이 둘은 비슷한 역할을 하지만, 세부적인 차이와 적합한 사용 사례를 이해하면 더 효과적으로 코드를 작성할 수 있습니다. 아래에서는 interface와 type의 차이를 전문적으로 분석하고, 사용 시 고려해야 할 점을 정리해보겠습니다.


1. 기본적인 정의와 공통점

interface와 type은 모두 TypeScript에서 객체, 함수, 배열, 클래스 등의 타입을 정의하는 데 사용됩니다. 다음은 두 방식의 공통점입니다.

공통점

  • 객체 형태를 정의할 수 있다.
  • 선택적 속성, 읽기 전용 속성 등을 지원한다.
  • 함수 타입을 정의할 수 있다.
 
// 공통적으로 지원하는 기능
interface ExampleInterface {
  name: string;
  age?: number; // 선택적 속성
}

type ExampleType = {
  name: string;
  age?: number;
};

// 함수 타입 정의
interface FuncInterface {
  (x: number, y: number): number;
}

type FuncType = (x: number, y: number) => number;​

2. interface의 특징

interface는 주로 객체의 형태를 정의하는 데 사용됩니다. TypeScript가 처음 설계될 때부터 제공된 기능이며, 여러 가지 확장과 상속 관련 기능을 제공합니다.

주요 특징

확장 가능 (Extensibility)

interface는 여러 인터페이스를 상속받아 확장할 수 있으며, 동일 이름의 인터페이스가 선언되면 자동으로 병합됩니다.

interface A {
  name: string;
}

interface B extends A {
  age: number;
}

interface A {
  address: string; // 기존 A에 병합
}

const person: B = { name: "Ji", age: 30, address: "Seoul" };

 

 

선언 병합 지원

동일한 이름의 interface를 여러 번 선언하면 병합됩니다. 이는 라이브러리 확장이나 전역 선언에 유용합니다.

 
interface Config {
  host: string;
}

interface Config {
  port: number;
}

const server: Config = { host: "localhost", port: 8080 };​
 

클래스와의 상호작용

클래스와 직접적으로 연결되어 구현(implements) 키워드를 통해 클래스의 타입을 강제할 수 있습니다.

interface Animal {
  sound(): void;
}

class Dog implements Animal {
  sound() {
    console.log("Woof!");
  }
}

3. type의 특징

type은 TypeScript 1.4 이후 도입된 기능으로, 유연한 타입 정의를 지원합니다. interface가 객체를 다루는 데 초점을 맞춘 반면, type은 더 다양한 타입(유니언, 인터섹션, 함수, 튜플 등)을 정의하는 데 적합합니다.

주요 특징

유니언(Union) 및 인터섹션(Intersection) 타입

type은 유니언(|)과 인터섹션(&)을 통해 복잡한 타입을 조합하는 데 강력합니다.

 
type A = { name: string };
type B = { age: number };

type C = A & B; // 인터섹션
type D = A | B; // 유니언

const obj1: C = { name: "Ji", age: 30 }; // A와 B 모두 포함
const obj2: D = { name: "Ji" }; // A 또는 B 중 하나​

튜플과 기타 타입 정의

튜플, 리터럴 타입, 또는 함수 타입을 간결하게 정의할 수 있습니다.

type TupleType = [string, number];
const tuple: TupleType = ["Ji", 30];

type LiteralType = "success" | "failure";
const status: LiteralType = "success";
 

별칭(Alias)으로 활용

기존 타입이나 유니언 타입에 새로운 이름을 붙여 재사용성을 높일 수 있습니다.

type ID = string | number;
const userId: ID = 12345;​

확장 불가

동일한 이름으로 선언 병합을 지원하지 않으며, 별도로 확장하려면 인터섹션(&)을 사용해야 합니다.


4. 주요 차이점 비교

특성 interface type
확장성 상속(extends) 및 선언 병합 지원 병합 불가, 인터섹션(&)으로 확장 가능
유니언 및 인터섹션 지원하지 않음 유니언(`
클래스와의 호환성 implements를 통해 클래스와 호환 직접적으로 클래스와 상호작용하지 않음
튜플 및 리터럴 타입 제한적 지원 강력한 지원
추천 용도 객체 타입 정의, 클래스와의 상호작용 복잡한 타입 조합, 유니언, 별칭 등

 


5. 어떤 것을 사용해야 할까?

interface를 추천하는 경우

  • 객체 타입 정의가 주된 목적일 때
  • 선언 병합이 필요한 경우 (특히 라이브러리 확장)
  • 클래스와 상호작용할 때

type을 추천하는 경우

  • 유니언 및 인터섹션 타입이 필요할 때
  • 튜플이나 리터럴 타입 정의가 필요할 때
  • 복잡한 타입 조합 또는 별칭(Alias)을 사용할 때

6. 결론

  • 단순한 객체 타입 정의에는 interface를 사용하는 것이 더 직관적이고 확장성이 좋습니다.
  • 유연한 타입 조합과 다양한 타입 정의에는 type이 더 적합합니다.
  • 실제로는 두 가지를 함께 사용해 프로젝트 요구 사항에 맞게 최적의 타입을 정의하는 것이 중요합니다.

이처럼 interface와 type은 각각의 장점과 적합한 용도가 있습니다. 프로젝트의 복잡도와 목적에 따라 적절히 선택하여 코드를 작성한다면 더 읽기 쉽고 유지보수하기 좋은 TypeScript 코드를 만들 수 있습니다. 😊

 

 

TS Interface / Type

 

 

 

반응형