티스토리 뷰

TypeScript를 사용하다 보면 가장 먼저 마주치는 고민 중 하나가 바로 **"객체의 타입을 정의할 때 interface를 쓸까, type을 쓸까?"**입니다. 과거에는 두 기능의 차이가 뚜렷했지만, 버전이 올라가면서 많은 기능이 공유되게 되었습니다.
오늘 포스팅에서는 이 둘의 공통점과 차이점, 그리고 실무에서 어떤 기준을 가지고 선택해야 하는지 풍부한 예제와 함께 알아보겠습니다.
1. 공통점: 둘 다 가능한 것들
현대 TypeScript에서 두 방식은 매우 유사하게 동작합니다. 대부분의 경우 서로 대체가 가능합니다.
1.1 객체의 구조 정의
가장 기본적인 용도인 객체 형태 정의는 두 방식 모두 동일하게 지원합니다.
// Interface 사용
interface UserInterface {
name: string;
age: number;
}
// Type Alias 사용
type UserType = {
name: string;
age: number;
};
const user1: UserInterface = { name: "John", age: 30 };
const user2: UserType = { name: "Jane", age: 25 };
1.2 확장(Inheritance)
이름은 다르지만 두 방식 모두 다른 타입을 확장하거나 결합할 수 있습니다.
// Interface: extends 키워드 사용
interface Animal {
species: string;
}
interface Dog extends Animal {
breed: string;
}
// Type: Intersection(&) 연산자 사용
type AnimalType = {
species: string;
};
type DogType = AnimalType & {
breed: string;
};
2. 결정적인 차이점
두 방식이 비슷해 보여도, 오직 한 쪽에서만 가능한 기능들이 있습니다.
2.1 선언 병합 (Declaration Merging) - Interface 전용
interface의 가장 독특한 특징입니다. 같은 이름으로 인터페이스를 여러 번 선언하면 TypeScript가 자동으로 이들을 하나로 합쳐줍니다.
interface Window {
title: string;
}
interface Window {
isMaximized: boolean;
}
// 결과적으로 Window는 title과 isMaximized를 모두 가짐
const myWindow: Window = {
title: "Main",
isMaximized: true
};
팁: 이 특징은 외부 라이브러리의 타입을 확장해야 할 때 매우 유용합니다. 반면 type은 같은 이름으로 중복 선언 시 오류가 발생합니다.
2.2 프리미티브, 유니온, 튜플 - Type 전용
type은 객체뿐만 아니라 모든 타입의 별칭을 만들 수 있습니다. interface는 오직 객체의 구조만을 정의할 수 있습니다.
// 프리미티브 타입 별칭
type MyString = string;
// 유니온 타입 (가장 많이 쓰임)
type Transport = 'Bus' | 'Subway' | 'Taxi';
// 튜플 타입
type Point = [number, number];
// interface로는 위와 같은 정의가 불가능합니다.
2.3 Computed Properties (Mapped Types)
복잡한 매핑 타입을 만들 때는 type이 훨씬 강력합니다.
type Keys = "firstname" | "surname";
type NameStruct = {
[K in Keys]: string;
};
const myName: NameStruct = {
firstname: "Gildong",
surname: "Hong"
};
3. 실무에서는 무엇을 써야 할까? (결론)
TypeScript 공식 문서와 커뮤니티의 일반적인 권장 사항은 다음과 같습니다.
✅ 인터페이스(Interface)를 추천하는 경우
- API의 형태를 정의할 때 (객체의 구조가 핵심일 때)
- 라이브러리 작성자가 되어 사용자가 타입을 확장할 수 있게 열어두고 싶을 때
- 클래스의 implements를 사용하여 설계 도면을 만들 때
✅ 타입 별칭(Type Alias)을 추천하는 경우
- Union 타입(|)이나 Intersection 타입(&)이 필요할 때
- **튜플(Tuple)**이나 기본 타입의 별칭이 필요할 때
- Mapped Types나 Conditional Types 등 복잡한 타입 로직이 들어갈 때
💡 한 줄 요약
"가능하다면 interface를 먼저 고려하고, 유니온 타입이나 복잡한 타입 연산이 필요해지는 시점에 type을 사용하세요."
일관성이 가장 중요합니다. 팀 내에서 컨벤션을 정했다면 그 규칙을 따르는 것이 최선입니다. 대부분의 현대 프로젝트에서는 객체 구조는 Interface, 그 외는 Type으로 나누어 사용하는 경향이 있습니다.
'Frontend > Typescript' 카테고리의 다른 글
| 제네릭(Generics) 완벽 가이드: 유연하고 안전한 코드를 위한 마법 같은 도구 (0) | 2026.02.19 |
|---|---|
| 안전한 코딩을 위한 필수 코스: 함수 타이핑 (매개변수, 반환 타입, 옵셔널 파라미터) (0) | 2026.02.19 |
| 기본 타입 정복: string, number, boolean부터 any, unknown, never의 차이점 (0) | 2026.02.19 |
| 환경 설정 완벽 가이드: Node.js 환경에서 tsconfig.json 설정법 및 개발 환경 구축 (0) | 2026.02.18 |
| 왜 TypeScript인가?: JS의 한계와 TS가 가져다주는 안정성 (0) | 2026.02.18 |
- Total
- Today
- Yesterday
- react
- MSA
- HBM
- LLM
- 엣지컴퓨팅
- 구글
- 카카오
- 웹기초
- AI
- SSR
- sLLM
- 스마트안경
- java
- 협력
- HTML
- on-device ai
- 멀티모달
- Rag
- It용어
- prompt engineering
- CSS
- Javascript
- Nextjs
- TypeScript
- CSR
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |