티스토리 뷰

타입스크립트(TypeScript)를 단순한 '타입 검사기'를 넘어 '설계 도구'로 활용하게 해주는 핵심 기능이 바로 유니온(Union)과 인터섹션(Intersection)입니다. 이 두 개념을 이해하면 정적인 타입 시스템 안에서도 놀라울 만큼 유연하고 확장성 있는 아키텍처를 구축할 수 있습니다.
본 포스팅에서는 실무에서 바로 활용할 수 있는 풍부한 예제와 함께 유니온과 인터섹션의 개념을 깊이 있게 살펴보겠습니다.
1. 유니온 타입 (Union Types): "또는 (OR)"
유니온 타입은 값의 타입을 여러 개 중 하나로 허용하고 싶을 때 사용합니다. 세로 바($|$) 기호를 사용하여 정의하며, 집합론적으로는 합집합의 개념입니다.
실무 예제: 다중 상태 관리
API 요청의 상태를 정의할 때 유니온 타입은 빛을 발합니다.
type NetworkStatus = 'loading' | 'success' | 'error';
function handleResponse(status: NetworkStatus) {
switch (status) {
case 'loading':
console.log("데이터를 불러오는 중입니다...");
break;
case 'success':
console.log("성공적으로 완료되었습니다.");
break;
case 'error':
console.log("에러가 발생했습니다.");
break;
}
}
함수 매개변수의 유연성
하나의 함수가 다양한 형태의 입력을 처리해야 할 때 유용합니다.
function formatId(id: string | number) {
if (typeof id === 'string') {
return `ID_${id.toUpperCase()}`;
}
return `ID_${id.toFixed(0)}`;
}
console.log(formatId("user123")); // ID_USER123
console.log(formatId(456.7)); // ID_457
2. 인터섹션 타입 (Intersection Types): "그리고 (AND)"
인터섹션 타입은 여러 타입을 하나로 결합하여 모든 타입의 기능을 갖춘 새로운 타입을 만듭니다. 앰퍼샌드($\&$) 기호를 사용하며, 집합론적으로는 교집합의 개념이지만, 객체 관점에서는 속성의 결합으로 이해하는 것이 쉽습니다.
실무 예제: 엔티티 확장
기본 사용자 정보에 권한 정보를 합쳐서 새로운 관리자 타입을 정의할 수 있습니다.
interface User {
id: string;
name: string;
}
interface Permissions {
canEdit: boolean;
canDelete: boolean;
}
// User와 Permissions의 모든 속성을 가져야 함
type AdminUser = User & Permissions;
const admin: AdminUser = {
id: "admin-01",
name: "관리자",
canEdit: true,
canDelete: true
};
3. 아키텍처적 진화: 식별 가능한 유니온 (Discriminated Unions)
단순한 유니온을 넘어, 객체 내부에 공통된 '태그'를 두어 타입을 안전하게 좁히는(Narrowing) 기법입니다. 이는 현대적인 상태 관리와 리듀서(Reducer) 패턴의 근간이 됩니다.
예제: 메시지 시스템 설계
interface TextMessage {
type: 'text'; // 식별자(Discriminant)
content: string;
}
interface ImageMessage {
type: 'image'; // 식별자(Discriminant)
url: string;
size: number;
}
interface VideoMessage {
type: 'video'; // 식별자(Discriminant)
url: string;
duration: number;
}
type Message = TextMessage | ImageMessage | VideoMessage;
function renderMessage(msg: Message) {
// 공통 속성인 'type'을 통해 타입 가드(Type Guard) 역할 수행
switch (msg.type) {
case 'text':
// 여기서 msg는 TextMessage 타입으로 자동 추론됨
console.log(`텍스트: ${msg.content}`);
break;
case 'image':
// 여기서 msg는 ImageMessage 타입으로 자동 추론됨
console.log(`이미지 링크: ${msg.url}, 크기: ${msg.size}KB`);
break;
case 'video':
console.log(`비디오 재생시간: ${msg.duration}초`);
break;
}
}
4. 유니온과 인터섹션의 조합
때로는 이 두 가지를 혼합하여 더욱 복잡한 비즈니스 로직을 표현할 수도 있습니다.
type ResponseBase = {
timestamp: number;
};
type SuccessResponse = ResponseBase & {
status: 'success';
data: string[];
};
type FailureResponse = ResponseBase & {
status: 'failure';
error: { code: number; message: string };
};
type ApiResponse = SuccessResponse | FailureResponse;
const handleApi = (response: ApiResponse) => {
if (response.status === 'success') {
console.log(response.data.length); // 안전하게 접근 가능
} else {
console.error(response.error.message); // 안전하게 접근 가능
}
};
결론: 왜 유니온과 인터섹션인가?
- 예측 가능성: 잘못된 속성 조합이 생성되는 것을 컴파일 단계에서 방지합니다.
- 재사용성: 작은 인터페이스들을 조합(Composition)하여 복잡한 도메인 모델을 구축할 수 있습니다.
- 가독성: 코드만 보고도 해당 데이터가 어떤 상태를 가질 수 있는지 명확히 파악할 수 있습니다.
타입스크립트 아키텍처 설계에서 유니온과 인터섹션은 단순히 타입을 나열하는 수단이 아닙니다. 이는 데이터 간의 관계를 정의하고 로직의 흐름을 안전하게 가이드하는 강력한 설계 언어입니다.
'Frontend > Typescript' 카테고리의 다른 글
| TypeScript 열거형(Enum) vs const 객체: 성능과 가독성 측면에서의 비교 분석 (0) | 2026.02.19 |
|---|---|
| 타입 가드(Type Guard): typeof, instanceof, is를 활용한 안전한 타입 좁히기 (0) | 2026.02.19 |
| 제네릭(Generics) 완벽 가이드: 유연하고 안전한 코드를 위한 마법 같은 도구 (0) | 2026.02.19 |
| 안전한 코딩을 위한 필수 코스: 함수 타이핑 (매개변수, 반환 타입, 옵셔널 파라미터) (0) | 2026.02.19 |
| TypeScript 인터페이스(Interface) vs 타입 별칭(Type Alias) 완벽 가이드 (0) | 2026.02.19 |
- Total
- Today
- Yesterday
- CSR
- prompt engineering
- Nextjs
- 스마트안경
- 구글
- SSR
- Javascript
- react
- LLM
- It용어
- CSS
- HBM
- java
- HTML
- 멀티모달
- TypeScript
- Rag
- AI
- 엣지컴퓨팅
- 웹기초
- sLLM
- MSA
- on-device ai
- 카카오
- 협력
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |