[TypeScript] type {함수명}? interface {함수명}?
오늘도 평화롭게 사탕을 하나 먹으며 코드 리팩토링 요소를 찾아보던 날이었습니다.
입안 가득 퍼지는 청포도 향이 좋다고 생각하다가 전에 타입을 지정할 때 interface와 type을 둘 다 썼던 것만 같은 기억이 문득 떠올랐습니다
그래서 확인을 해 보았는데 실제로도 두개가 혼용되어서 사용이 되고 있는 것을 볼 수 있었습니다.
그 때 갑자기 머릿속에서 들려오는 질문 하나가 있었습니다.
"타입이랑 인터페이스랑 뭐, 똑같은 거 아닌가?" 분명 머리로는 아니라는 걸 알지만 자세히 알지 못하였기에
바로 블로그에 접속해서 기록하며 알아보기 시작했습니다.
**type**과 **interface**는 TypeScript에서 사용되는 두 가지 기능입니다.
이 둘은 비슷해 보이지만, 몇 가지 차이점이 있기에 지금부터 알아보려고 해요.
그 전에, 왜 이 둘이 헷갈릴만 하는 지에 대해 제가 겪은 상황과 비슷한 두 개의 코드를 보여드릴게요.
(아래의 코드들은 예시로 실제로 이렇게 작성한 것은 아닙니다)
type User = {
id: number;
name: string;
email: string;
};
interface User {
id: number;
name: string;
email: string;
}
저의 경우에는 그저 단순하게 1차적인 타입만들 지정 해두었던 그러한 코드들을 만들다 보니 위와 같은 모양들이 나왔습니다.
그래서 하고싶은 말이 무엇이냐?
"헷갈릴만 하죠?"
정말 무슨 차이인지 단 하나도 모르겠을 코드들을 보며 저는 잠시 고민을 했었습니다.
그럼 이제 type과 interface의 차이점을 알아보도록 할게요!
- 구문: **type**은 별칭을 만들 때 사용하고, **interface**는 객체의 구조를 만들 때 사용해요.
- 여기서 "별칭"은 type을 사용하여 정의한 타입을 다른 이름으로 참조할 수 있게 해주는 것을 의미합니다. 즉, 한 타입을 더 짧고 쉽게 사용할 수 있는 이름으로 나타내는 것입니다.
- 그리고 "구문"(syntax)은 프로그래밍 언어에서 코드를 작성하는 방식이나 규칙을 의미합니다. 구문은 언어의 문법과 비슷하게, 코드가 어떻게 작성되어야 하는지를 규정합니다.
- type과 interface에서의 구문 차이는 두 기능이 어떻게 작성되고 사용되는지에 대한 차이라고 보면 돼요.
type Coordinate = {
x: number;
y: number;
};
type DistanceFunction = (a: Coordinate, b: Coordinate) => number;
interface Coordinate {
x: number;
y: number;
}
interface DistanceFunction {
(a: Coordinate, b: Coordinate): number;
}
- 인터페이스 병합: 같은 이름의 인터페이스를 여러 번 선언하면 자동으로 합쳐집니다. 그런데 type은 합쳐지지 않아요.
interface Vehicle {
wheels: number;
}
interface Vehicle {
color: string;
}
// Vehicle 인터페이스는 { wheels: number; color: string; } 로 병합됩니다.
type Vehicle = {
wheels: number;
};
// 이렇게 하면 오류가 발생합니다. 이미 Vehicle이 선언되었기 때문입니다.
type Vehicle = {
color: string;
};
어찌보면 interface는 var과 비슷하고, type은 let,const와 비슷하네요?
- 클래스 구현: 인터페이스는 클래스가 구현할 수 있지만, type은 그렇지 않아요.
interface Runnable {
run(): void;
}
class Car implements Runnable {
run() {
console.log("Car is running");
}
}
type Runnable = {
run(): void;
};
// 오류 발생: 클래스는 type을 구현할 수 없습니다.
class Car implements Runnable {
run() {
console.log("Car is running");
}
}
- 확장: 인터페이스는 다른 인터페이스를 확장할 수 있지만, type은 그렇지 않아요.
interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
type Animal = {
name: string;
};
// type 확장에는 인터섹션(intersection)을 사용해야 합니다.
type Dog = Animal & {
breed: string;
};
이런 차이점이 있지만, 대부분의 경우 type과 interface를 혼용해서 사용할 수 있어요. 상황에 맞게 적절한 도구를 사용하면 코드가 더 깔끔하고 관리하기 쉬워집니다!
우와! 이렇게 열심히 알아보다보니 사탕 하나를 다 먹었네요!
생각해보면 type은 사탕처럼 합쳐질 수 없다는 점이, interface는 카라멜처럼 합쳐질 수 있다는 점이 같다는 꿀팁이 있었네요!
이번 글은 여기서 마치도록 하겠습니다. 다들 좋은 하루 되시길 바래요!
요약
TypeScript에서 type과 interface는 비슷한 목적으로 사용되지만, 몇 가지 차이점이 있습니다.
- 구문: type은 별칭(alias)을 만들 때 사용하고, interface는 객체의 구조를 만들 때 사용합니다.
- 인터페이스 병합: 같은 이름의 인터페이스는 자동으로 합쳐집니다. 그러나 type은 합쳐지지 않습니다.
- 클래스 구현: 인터페이스는 클래스가 구현할 수 있지만, type은 그렇지 않습니다.
- 확장: 인터페이스는 다른 인터페이스를 확장할 수 있지만, type은 그렇지 않습니다. type 확장에는 인터섹션(intersection)을 사용해야 합니다.
상황에 따라 적절한 도구를 사용하면 코드가 더 깔끔하고 관리하기 쉬워집니다. 이제 type과 interface의 차이점을 알았으니, 앞으로 코드 리팩토링을 할 때 더욱 효율적으로 작업할 수 있을 것입니다. 다들 좋은 하루 되시길 바랍니다!
End