🔽 TypeScript에서 type과 interface의 차이 및 선택 기준
최근에 TypeScript에서 데이터를 패치하고 받아오는 과정에서 데이터 response의 타입을 지정할 때, type과 interface 중 무엇을 써야 할지 고민이 생겼는데요.
두 가지 모두 객체의 구조를 정의할 수 있지만, 각각의 특징과 차이점이 존재합니다.
오늘은 이 내용에 대해 정리해보고자 합니다!
🔽 type alias, interface
타입스크립트에서 객체 타입을 지정하는 방식으로 거의 비슷한 기능을 가진다.
type B = {
a: string;
b: number;
};
interface C {
a: string;
b: number;
}
🔽 확장 방식
type alias
type TA = {
a: string;
};
type TB = {
b: string;
};
type TC = TA & TB & { k: string };
interface
interface IA {
a: string;
}
interface IB {
b: string;
}
interface IC extends IA, IB {
k: string;
}
🔽 공통점
- 객체의 구조(프로퍼티와 타입)를 정의할 수 있다.
- 실제 사용법(타입 지정, 변수 선언 등)이 거의 비슷하다.
- 제네릭을 지원한다.
🔽 주요 차이점
| 구분 | type | interface |
| 확장 | 교차 타입(&), 유니온 등 다양한 방식으로 확장 가능 | extends 키워드를 사용하여 다른 interface를 상속(확장)할 수 있음 |
| 선언적 확장 | 불가 (동일 이름 중복 선언 시 에러) | 가능 (동일 이름 interface 선언 시 자동 병합) |
| 표현 가능 범위 | 객체, 원시타입, 유니온, 튜플 등 거의 모든 타입 표현 | 객체 타입만 표현 가능 |
| 복잡한 타입 | 유니온, 인터섹션, 튜플 등 복잡한 타입 조합 가능 | 불가 (객체 구조 정의에 최적화) |
| 사용 권장 | 복잡한 타입 조합, 유니온/인터섹션 필요 시 | 객체 구조 정의, 라이브러리/공용 타입 정의 시 |
🔽 언제 type을 쓰고 언제 interface를 쓸까?
- 객체의 구조를 정의하고, 확장이나 상속(extends)이 필요한 경우특히 라이브러리, API 응답 객체 등 재사용 및 확장이 필요한 경우 interface가 적합하다.
→ interface 사용 권장. - 유니온 타입, 튜플, 원시 타입, 복잡한 타입 조합이 필요한 경우예를 들어, type Response = string | number | MyObject; 처럼 다양한 타입을 조합할 때 type이 더 유연하다.
→ type 사용 권장. - 전역적으로 확장되어야 하거나, 여러 곳에서 병합이 필요한 타입interface는 동일 이름으로 여러 번 선언해도 자동으로 병합된다.
→ interface가 유리하다. - 단순히 타입을 한 번만 정의하거나, 복잡한 타입 조합이 필요할 때
→ type이 간결하다.
🔽 공식 문서 및 커뮤니티 권장사항
For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type.
- "모르겠으면 일단 interface를 사용하라"는 것이 공식 문서의 권장사항이다.
- 실제로 TypeScript는 대부분의 경우 두 방식 모두 허용하며, 필요에 따라 혼용도 가능하다.
🔽 결론 및 실전 팁
- API response와 같이 객체 구조가 명확하고, 추후 확장 가능성이 있다면 interface를 사용하는 것이 좋다.
- 유니온, 튜플, 복잡한 타입 조합이 필요하다면 type을 사용하자.
- 팀의 스타일 가이드나 프로젝트의 특성에 따라 일관성 있게 사용하는 것이 가장 중요하다.
interface는 명확하게 객체를 정의하고 확장할 때 유용하며, type은 복잡한 타입 조합이 필요할 때 사용하기 좋습니다.
🔽 예시
// interface 사용 예시 (API 응답 객체)
interface UserResponse {
id: number;
name: string;
email: string;
}
// type 사용 예시 (유니온 타입 등)
type ResponseStatus = 'success' | 'error';
type ResponseData = UserResponse | null;
type ApiResponse = {
status: ResponseStatus;
data: ResponseData;
};
🔽 그래서 언제 뭘 써야 하나 (요약)
- 객체 구조 정의와 확장 → interface
- 복잡한 타입 조합, 유니온/튜플 → type
- 공식 권장: 모르겠으면 interface, 필요하면 type
- 두 방식 모두 혼용 가능, 상황에 맞게 선택
🔽 참고자료