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 코드를 만들 수 있습니다. 😊
'Frontend' 카테고리의 다른 글
TypeScript 관련 질문 (0) | 2024.12.15 |
---|---|
ES6+ 관련 질문 (0) | 2024.12.15 |
아이데이션(Ideation): 창의적 사고의 출발점 (0) | 2024.12.04 |
웹 개발 속도와 효율성을 높이는 최신 빌드 도구 비교(Vite, Webpack, Parcel, esbuild) (0) | 2024.12.02 |
2024년 Node.js 패키지 매니저 비교: npm, Yarn, pnpm, Rush의 장단점과 선택 가이드 (0) | 2024.12.02 |