Interface 와 Type 의 차이점

낭만감자·2024년 11월 12일
0

TIL

목록 보기
1/5
post-thumbnail

타입스크립트를 사용하면서 타입을 정의할 때 interface 또는 type을 사용할 수 있습니다.

두 개 차이가 뭔지 항상 궁금하긴 했지만 극강의 귀차니즘으로 인해 애써 흐린눈하며.. 그저 글자수가 더 적은 type 만을 고집해왔는데요. .ㅎ

이제는 더이상 물러날 수가 없겠다는 생각이 들어 이 둘의 차이에 대해 공부해보았습니다 !

1. Interface란 ?

1-1. Typescript 에서 Interface의 활용

💡객체의 구조 정의

user 라는 객체에 어떤 속성이 들어가고, 해당 value의 타입은 무엇인지를 구체적으로 정의해줍니다.

interface User {
  name: string;
  age: number;
  isAdmin: boolean;
}

const user: User = {
  name: "Alice",
  age: 25,
  isAdmin: true,
};

💡함수의 파라미터 타입, 함수 타입 정의

함수의 파라미터 타입을 명시할 수 있습니다.
아래코드에서는 매개변수로 받는 product 의 타입을 명시합니다.

예를들어 product인데 user 정보를 넘겨줄 경우 오류가 나겠죠!

interface Product {
  name: string;
  price: number;
  inStock: boolean;
}

function printProductDetails(product: Product): void {
  console.log(`${product.name} costs $${product.price} and is ${product.inStock ? "in stock" : "out of stock"}`);
}

printProductDetails({ name: "Laptop", price: 999.99, inStock: true });

함수의 형태를 정의합니다.
아래 코드는 greet 라는 무엇을 매개로 받고, 무엇을 반환하는지 나타냅니다.

interface Greet {
  (name: string): string;
}

const greet: Greet = (name) => {
  return `Hello, ${name}!`;
};

console.log(greet("Alice")); // "Hello, Alice!"

💡클래스에 인터페이스 구현

특정 클래스가 반드시 정의해야 할 속성과 메서드를 강제할 수 있습니다. 이때 implements 라는 키워드를 사용합니다.

아마 JAVA를 공부하셨던 분이라면 익숙하실거예요

interface Animal {
  name: string;
  makeSound(): void;
}

class Dog implements Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  makeSound() {
    console.log("Woof!");
  }
}

const myDog = new Dog("Buddy");
myDog.makeSound(); // "Woof!"

💡 인터페이스 확장 (상속)

인터페이스는 다른 인터페이스를 확장하여 더 복잡한 구조를 정의할 수 있습니다.
type 과의 가장 큰 차이점이라고도 할 수 있을 것같아요.

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

interface Employee extends Person {
  employeeId: number;
  role: string;
}

const employee: Employee = {
  name: "John",
  age: 30,
  employeeId: 123,
  role: "Developer",
};

1-2. interface 의 구조 확장 예시

인터페이스를 확장해서 쓸 생각은 한번도 해보지 못했는데, 인터페이스를 확장한다면 조금 더 가독성이 높아지고, 중복코드를 방지할 수 있을것같다는 생각이 들었습니다.

예를들어 User Type , UserJoinType , UserProfileType 을 사용한다고 했을 때,

interface UserType {
  name: string;
  phone: string;
}

interface UserJoinType extends UserType {
  password: string;
  confirmPassword: string;
  verifiedNumber: number;
}
interface UserProfileType extends UserType {
  profilePicture: string;  
  bio: string;             
  address: string;         
  joinedDate: Date;        
}

이렇게 타입을 선언하는 과정에서 겹치는 부분은 굳이 다시 쓰지 않아도 된다는 장점이 있습니다.

const user: UserType = {
  name: "Alice",
  phone: "123-456-7890",
};

const userJoin: UserJoinType = {
  name: "Alice",
  phone: "123-456-7890",
  password: "password123",
  confirmPassword: "password123",
  verifiedNumber: 1234,
};
const userProfile: UserProfileType = {
  name: "Alice",
  phone: "123-456-7890",
  profilePicture: "https://example.com/profile.jpg",
  bio: "Hello, I'm Alice! I love coding and hiking.",
  address: "123 Maple St, Somewhere, Earth",
  joinedDate: new Date("2023-01-15"),
};

2. Type 이란?

2-1. TypeScript 에서 Type 의 활용

type 이라는 이름에서 알 수 있듯이, 타입을 정의할 때 사용하는 키워드입니다.
type 별칭을 만들어서 여러 상황에서 유연하게 활용할 수 있다는 것이 가장 큰 특징입니다.

interface 보다는 조금 더 좁은 개념으로 받아들일 수 있을것같아요.

💡기본 타입 별칭 만들기

기본적인 자료형 string, number 에도 ID 라는 별칭을 만들어서 사용할 수 있습니다.
매번 string ,number 를 넣어주는 것보다 가독성도 높아지고, 일관성을 유지할 수 있겠죠.

type ID = string | number;

let userId: ID = "12345";
let orderId: ID = 67890;

💡객체/함수/튜플 의 타입 정의

객체 구조를 type 으로 정의하여 반복적으로 사용할 수 있습니다.
동일한 구조의 객체를 여러번 사용할 경우 유용합니다 .

type Product = {
  name: string;
  price: number;
  inStock: boolean;
};

const apple: Product = {
  name: "Apple",
  price: 1.5,
  inStock: true,
};

💡유니온 타입 사용

interface 와 가장 큰 차이점이라고 생각하는 부분입니다.
type을 사용하면 다양한 타입을 유니온 타입으로 정의할 수 있습니다.

type ButtonSize = "small" | "medium" | "large";
type ButtonColor = "primary" | "secondary" | "danger";

function createButton(size: ButtonSize, color: ButtonColor) {
  console.log(`Creating a ${size} button with ${color} color.`);
}

createButton("medium", "primary");

💡교차 타입 생성

interface 의 확장과 비슷하게 & 를 사용하여 교차 타입을 만들 수 있습니다.

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

type Contact = {
  phone: string;
  email: string;
};

type Employee = Person & Contact;

const employee: Employee = {
  name: "Alice",
  age: 30,
  phone: "123-456-7890",
  email: "alice@example.com",
};

3. Interface 와 Type 의 차이

이 두가지의 차이를 간단하게 정리하면 다음과 같습니다.

3-1. 구조 확장

Interface는 선언 병합을 통해 여러 번 확장이 가능합니다. 같은 이름의 인터페이스를 여러 곳에서 선언하면 자동으로 병합되어 하나의 구조로 만들어집니다.

Type은 확장 불가이며, 선언 병합을 지원하지 않습니다. 이미 선언된 타입을 다시 선언할 수 없고, 확장을 위해서는 유니온 타입 또는 & 연산자를 사용합니다.

3-2. 선언과 사용 방식

Interface는 객체의 구조를 주로 정의할 때 사용하며, 클래스의 구현 타입으로도 많이 사용됩니다.

Type은 기본 자료형(문자열, 숫자 등)에 대한 타입별칭을 정의하거나, 유니온 타입, 튜플 등으로도 정의가 가능합니다.

3-3. 유니온 타입 정의

Interface는 유니온 타입을 지원하지 않아, 특정 구조의 객체를 위한 타입만 정의할 수 있습니다.

Type | 연산자를 사용해 유니온 타입을 정의할 수 있습니다. 예를 들어, type Shape = Circle | Square;처럼 다양한 구조를 합쳐 하나의 타입으로 정의할 수 있습니다.

4. 언제 Interface 를 ,언제 Type 을 사용하는 것이 좋을까?

💡interface를 사용하는 경우

  • 객체의 구조를 명확히 정의하고, 선언 병합을 통해 여러 곳에서 확장이 필요한 경우.
  • 클래스의 타입 정의나 구현체를 명시할 때.

💡type을 사용하는 경우

  • 유니온 타입을 정의해야 할 때.
  • 기본 자료형의 타입 별칭을 만들거나, 튜플을 정의할 때.
  • 객체의 구조 외에 다양한 타입 구성이 필요한 경우 (예: 함수 시그니처, 유니온 타입 등).

마무리

이렇게 직접 interface 와 type의 차이점을 공부하다보니 지금 하고있는 프로젝트에서 어떤 부분을 수정해야 할지 감이 오는것같습니다.

지금까지는 type 으로만 주구장창 정의했었는데, 몇개는 interface 로 변경을 해서 중복되는 부분을 줄이고, 비슷한 성질을 가진 것끼리 잘 묶여지도록 수정할 수 있을것같네요. 이렇게 수정한다면 아예 제 코드를 처음보는 사람이 유지보수를 하게 될 때에도 조금 더 편하고 빠르게 파악할 수 있을것같습니다.

복잡하지 않은 서비스에서는 interface 를 쓰든, type을 쓰든 성능이나 가독성이나 크게 문제가 될 건 없겠지만 지금부터라도 이렇게 어떤 상황에서 무엇을 사용하는 것이 더 적절한건지 파악하고, 의도를 가지고 골라 사용하는 습관을 가지게 된다면 더 좋은 개발자가 될 수 있을것같습니다.

무엇이든지 '그냥' 하는 것이 아니라 '의도를 가지고'하는 것이 중요하니까요 !

profile
웹 프론트엔드 취준생 🥔

0개의 댓글

관련 채용 정보