[Typescript] 인터페이스(interface), 타입(type) 차이

해피몬·2023년 9월 3일
post-thumbnail

정의

인터페이스 (Interface)

인터페이스는 주로 객체의 구조를 정의할 때 사용됩니다. 객체가 가져야 할 속성과 메서드를 지정하고, 객체가 해당 구조를 따르도록 강제합니다. TypeScript에서는 인터페이스를 사용해 객체의 형태를 선언할 수 있으며, 클래스에서도 구현(implement)할 수 있습니다.

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

const person: Person = {
  name: 'Alice',
  age: 25,
};

타입 (Type Alias)

타입은 타입의 별칭을 정의하는 데 사용됩니다. 객체의 구조뿐만 아니라, 원시 타입, 유니언, 튜플 등 다양한 타입에 대해 별칭을 지정할 수 있어 유연하게 사용할 수 있습니다.

type Person = {
  name: string;
  age: number;
};

const person: Person = {
  name: 'Alice',
  age: 25,
};

차이

1) 확장 방법의 차이

인터페이스는 다른 인터페이스를 상속하여 확장할 수 있으며, 이는 객체의 구조를 재사용하는 데 유용합니다. 타입은 인터섹션 타입(&)을 사용해 확장할 수 있습니다.

인터페이스는 extends 키워드를 사용해 상속할 수 있지만, 타입은 & 연산자를 통해 확장합니다.

// 인터페이스 확장 예시
interface Animal {
  name: string;
}

interface Dog extends Animal {
  breed: string;
}

const myDog: Dog = {
  name: 'Buddy',
  breed: 'Golden Retriever',
};

// 타입 확장 예시
type Animal = {
  name: string;
};

type Dog = Animal & {
  breed: string;
};

const myDog2: Dog = {
  name: 'Buddy',
  breed: 'Golden Retriever',
};

2) 중복 선언 가능 여부

인터페이스는 동일한 이름으로 중복 선언이 가능하며, 이 경우 선언이 자동으로 병합됩니다. 반면, 타입은 중복 선언이 불가능하여 중복 선언 시 오류가 발생합니다.

인터페이스는 중복 선언 시 병합되므로 여러 소스에서 구조를 확장할 수 있는 반면, 타입은 중복 선언이 불가능해 별도의 타입을 정의해야 합니다.

// 인터페이스 병합
interface User {
  name: string;
}

interface User {
  age: number;
}

// User 타입은 name과 age를 모두 포함
const user: User = {
  name: 'Alice',
  age: 30,
};

// 타입 별칭의 중복 선언 오류
type UserType = {
  name: string;
};

type UserType = { // 오류: 중복 선언 불가
  age: number;
};

3) 유니언 타입과 같은 고급 타입 사용

타입은 유니언 타입이나 튜플과 같은 다양한 타입 정의에 사용할 수 있지만, 인터페이스는 객체의 형태를 정의하는 데 초점이 맞춰져 있어 이와 같은 사용이 불가능합니다.

타입은 유니언 타입, 튜플 등으로 다양한 형태의 타입을 표현할 수 있는 반면, 인터페이스는 객체 구조 정의에 특화되어 있습니다.

// 타입 별칭으로 유니언 타입 정의
type StringOrNumber = string | number;

const value1: StringOrNumber = 'Hello';
const value2: StringOrNumber = 123;

// 인터페이스에서는 유니언 타입 정의 불가
interface StringOrNumber { // 오류
  // 유니언 타입 정의 불가
}

4) 클래스에서의 사용

인터페이스는 클래스에서 구현(implements) 할 수 있지만, 타입은 클래스에서 직접 구현할 수 없습니다. 클래스와 인터페이스는 상호 호환이 잘 되므로, 객체의 구조를 정의할 때 인터페이스가 더 적합할 수 있습니다.

인터페이스는 클래스에 의해 구현될 수 있어 객체의 구조와 행동을 명확히 정의하는 데 유용합니다. 타입은 클래스에서 implements로 사용할 수 없습니다.

interface Person {
  name: string;
  speak(): void;
}

class Employee implements Person {
  constructor(public name: string) {}
  speak() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const employee = new Employee('Alice');
employee.speak(); // Hello, my name is Alice

언제 사용할까?

인터페이스를 사용할 때

1) 객체의 구조 정의: 주로 객체의 형태를 정의할 때 인터페이스가 적합합니다. 특히 클래스가 특정 구조를 따라야 할 때 유리합니다.
2) 중복 선언으로 병합이 필요한 경우: 여러 파일에 걸쳐 동일한 인터페이스를 정의하거나 확장할 때 병합 기능이 유용할 수 있습니다.
3) 클래스와의 연동: 클래스와 상호작용이 많은 경우 인터페이스를 통해 객체 구조를 명확히 정의하는 것이 좋습니다.

타입을 사용할 때

1) 복합 타입 정의: 유니언, 튜플, 원시 타입 등 다양한 타입을 정의해야 하는 경우 타입을 사용하는 것이 적합합니다.
2) 고정된 구조가 필요한 경우: 병합이 필요하지 않고, 특정 구조를 고정하여 사용하고자 할 때 타입 별칭이 유용합니다.
3) 함수, 유니언 타입 등 다양한 사용: 타입 별칭은 함수 타입 정의, 복합 타입 정의에도 유리하므로, 객체 구조 외에도 폭넓게 사용해야 할 때 적합합니다.

profile
슬기로운개발생활🤖

0개의 댓글