인터섹션 타입 (Intersection Types)
TypeScript에서 인터섹션 타입은 여러 타입을 모두 만족하는 하나의 타입을 표현한다.
집합 이론에서의 교집합 (A ∩ B) 개념과 동일하며, & 기호를 사용한다.
🧩 대수 타입(Algebraic type)이란?
대수 타입은 여러 개의 타입을 조합해서 새로운 타입을 만드는 방식을 말한다.
TypeScript에서는 대표적으로 Union Type과 Intersection Type이 있다.
Union Type: 여러 타입 중 하나를 허용하는 타입Intersection Type: 여러 타입을 모두 만족해야 하는 타입
1. 기본 사용법
인터섹션 타입은 & 기호를 사용하여 여러 타입을 합친다.
결합된 타입은 각 타입이 가진 속성을 모두 가져야 한다.
ts
type Name = { name: string };
type Age = { age: number };
// 인터섹션
type Person = Name & Age;
let user: Person = {
name: 'Hyebin',
age: 20,
};
let user2: Person = {
name: 'Bin',
}; // Error: age 속성이 없음Person은Name과Age를 모두 만족해야 한다.- 따라서
name과age속성을 모두 가져야 한다.
2. 여러 개의 타입 결합
인터섹션 타입은 두 개 이상의 타입도 결합할 수 있다.
ts
type Name = { name: string };
type Age = { age: number };
type Contact = { email: string };
type Employee = Name & Age & Contact;
let worker: Employee = {
name: 'Binny',
age: 30,
email: 'binny@email.com',
};Employee는Name,Age,Contact를 모두 만족해야 한다.- 따라서
name,age,email속성을 전부 포함해야 한다.
3. 유니언 타입과 인터섹션 타입 비교
유니언 | : 여러 타입 중 하나만 만족하면 된다.인터섹션 &: 여러 타입을 전부 만족해야 한다.
ts
type Cat = { meow: () => void };
type Dog = { bark: () => void };
// 유니언 타입
let pet1: Cat | Dog;
pet1 = { meow: () => console.log('야옹') };
pet1 = { bark: () => console.log('멍멍') };
// 인터섹션 타입
let pet2: Cat & Dog;
pet2 = {
meow: () => console.log('야옹'),
bark: () => console.log('멍멍'),
};pet1은Cat이거나Dog이면 된다.pet2는Cat과Dog를 모두 만족해야 하므로meow와bark를 모두 가지고 있어야 한다.
4. 실전 예시: API 응답 타입
인터섹션 타입은 공통 타입에 추가 타입을 결합할 때 자주 사용된다.
예를 들어 API 응답에서 공통 응답 구조와 실제 데이터 구조를 합칠 수 있다.
ts
type ApiResponse = {
status: number;
message: string;
};
type UserData = {
id: string;
name: string;
};
type UserResponse = ApiResponse & {
data: UserData;
};
const response: UserResponse = {
status: 200,
message: 'OK',
data: {
id: '1',
name: 'Hyebin',
},
};UserResponse는ApiResponse가 가진status,message와
추가로data속성을 모두 가져야 한다.- 이처럼 인터섹션 타입을 사용하면 공통 타입을 재사용하면서 필요한 속성을 추가할 수 있다.
5. 주의
인터섹션 타입은 객체 타입을 결합할 때는 속성을 합치는 것처럼 동작한다.
하지만 서로 겹칠 수 없는 타입을 결합하면 사용할 수 없는 타입이 될 수 있다.
ts
type Impossible = string & number;string이면서 동시에number인 값은 존재할 수 없다.
따라서 이런 타입은 사실상 사용할 수 없다.
객체에서도 같은 속성 이름에 서로 다른 타입을 지정하면 문제가 생길 수 있다.
ts
type A = {
id: string;
};
type B = {
id: number;
};
type C = A & B;C타입의id는string이면서 동시에number여야 한다.- 하지만 그런 값은 존재할 수 없기 때문에
id는 사용할 수 없는 타입이 된다.
ts
let value: C = {
id: 1, // Error
};- 따라서 인터섹션 타입을 사용할 때는 같은 속성 이름이 서로 충돌하지 않는지 확인하는 것이 좋다.