---
id: wiki-2026-0508-교집합-타입-intersection-type
title: 교집합 타입(Intersection Type)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Intersection Type, "&-Type", TypeScript Intersection]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, intersection, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: typescript
  framework: typescript-5.7
---

# 교집합 타입(Intersection Type)

## 매 한 줄
> **"매 `A & B` 의 모든 멤버를 동시 소유 — 매 type-level AND"**. 매 TypeScript 1.6 (2015) 도입 후 mixin / props composition / branded type 의 backbone. 매 union (`|`) 의 dual — 매 caller-side 의 broader requirement, callee-side 의 stricter guarantee.

## 매 핵심

### 매 의미론
- `A & B` = "매 A 이면서 동시 B인 값" — 매 set theory 의 intersection 과 dual (구조 의 union).
- 매 primitive intersection (`string & number`) 의 `never` — 매 incompatible.
- 매 object intersection 의 property merge — 매 conflict 시 narrower type 채택.
- 매 method overload signature 의 자동 intersection.

### 매 union 과의 차이
- `A | B`: 매 caller 의 selection — narrowing 필요.
- `A & B`: 매 caller 의 superset 요구 — 매 모든 capability 의 동시 제공.
- 매 distributivity: `(A | B) & C ≡ (A & C) | (B & C)`.

### 매 응용
1. Mixin composition (Loggable & Serializable & Comparable).
2. Props extension (BaseProps & VariantProps).
3. Branded / nominal typing (string & {__brand: 'UserId'}).
4. Function overload aggregation.

## 💻 패턴

### Mixin Composition
```typescript
type Timestamped = { createdAt: Date; updatedAt: Date };
type SoftDeletable = { deletedAt: Date | null };
type Auditable = { createdBy: string; updatedBy: string };

type Entity<T> = T & Timestamped & SoftDeletable & Auditable;

type User = Entity<{ id: string; email: string }>;
// User has: id, email, createdAt, updatedAt, deletedAt, createdBy, updatedBy
```

### Branded Type (nominal)
```typescript
type Brand<T, B> = T & { readonly __brand: B };

type UserId = Brand<string, 'UserId'>;
type OrderId = Brand<string, 'OrderId'>;

const asUserId = (s: string): UserId => s as UserId;

function getUser(id: UserId) { /* ... */ }
getUser('raw-string'); // ❌ Error
getUser(asUserId('u_123')); // ✅
```

### Component Props Extension
```typescript
import { ComponentPropsWithoutRef } from 'react';

type ButtonVariants = {
  variant?: 'primary' | 'secondary' | 'ghost';
  size?: 'sm' | 'md' | 'lg';
};

type ButtonProps = ComponentPropsWithoutRef<'button'> & ButtonVariants;

const Button = ({ variant = 'primary', size = 'md', ...rest }: ButtonProps) => (
  <button data-variant={variant} data-size={size} {...rest} />
);
```

### Conditional Intersection (discriminated)
```typescript
type WithLoading<T> = T & ({ loading: true; data?: undefined } | { loading: false; data: T });

type UserResource = WithLoading<{ name: string }>;
// Forces caller to check `loading` before reading `data`
```

### Function Overload via Intersection
```typescript
type Reader = ((path: string) => string) & ((path: string, encoding: 'utf8') => string) & ((path: string, encoding: 'binary') => Buffer);

const read: Reader = ((path: string, enc?: string): any => {
  // implementation
}) as Reader;
```

### Interface vs Intersection
```typescript
// Interface: open, mergeable, can extend
interface A { x: number }
interface A { y: number } // declaration merging
interface C extends A { z: number }

// Intersection: closed, computed
type A2 = { x: number } & { y: number };
type C2 = A2 & { z: number };
// A2 cannot be re-opened
```

### Distribute over Union
```typescript
type Distribute<T, U> = T extends any ? T & U : never;

type R = Distribute<{ a: 1 } | { b: 2 }, { c: 3 }>;
// = ({ a: 1 } & { c: 3 }) | ({ b: 2 } & { c: 3 })
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| Library 의 extension point | `interface` (declaration merging) |
| Inline type composition | `&` intersection |
| Nominal/branded type | `T & { __brand }` |
| Discriminated state | union of intersections |
| Conflicting properties | refactor — `&` 의 conflict 의 `never` 도출 |

**기본값**: 매 closed/local composition 의 `&`. 매 extensible API 의 `interface`.

## 🔗 Graph
- 부모: [[TypeScript Type System]]
- 응용: [[Branded Types]]

## 🤖 LLM 활용
**언제**: 매 props composition / mixin / branded ID 생성 시.
**언제 X**: 매 deep inheritance hierarchy — 매 class extends 의 사용. 매 runtime polymorphism 의 X.

## ❌ 안티패턴
- **Primitive intersection**: `string & number` → `never`. 매 의도적 X.
- **Conflicting property**: `{a: string} & {a: number}` → `a: never`. 매 silent bug.
- **Over-composition**: 7+ intersection chain — 매 compile time 폭발 + IntelliSense 깨짐.
- **Interface 대용 의 남용**: 매 public API 의 `interface` 가 더 적합 (mergeable, extends).

## 🧪 검증 / 중복
- Verified (TypeScript Handbook — Object Types, Microsoft 2026).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — TS intersection type FULL writeup |
