πŸŽ‰ berenickt λΈ”λ‘œκ·Έμ— 온 κ±Έ ν™˜μ˜ν•©λ‹ˆλ‹€. πŸŽ‰
Lang
TypeScript
05-Union & Intersection

1. Union (ν•©μ§‘ν•©, |)

Union(μœ λ‹ˆμ–Έ) : ν•˜λ‚˜λ‘œ λ­‰μ³μ§€λŠ” 것, μ‘°ν•©

  • e.g. Unit : ν•˜λ‚˜λ‘œ μ›€μ§μ΄λŠ” μ΅œμ†Œ λ‹¨μœ„, (μƒν’ˆμ˜) 1개, (νŠΉμ • μž„λ¬΄λ₯Ό μœ„ν•œ) λΆ€λŒ€ | 단체
  • e.g. Unity : ν•˜λ‚˜λ‘œ 뭉쳐진 μ‚¬λžŒλ“€μ˜ 마음, μ •μ„œ λ“±
1
// 4κ°€μ§€ νƒ€μž…μ„ κ°€μ§ˆ 수 μžˆλŠ” Direction νƒ€μž…----------------------
2
type Direction = 'left' | 'right' | 'up' | 'down'
3
function move(direction: Direction) {
4
console.log(direction)
5
}
6
move('down')
7
8
// 3κ°€μ§€ νƒ€μž…μ„ κ°€μ§€λŠ” TileSizeνƒ€μž…-------------------------------
9
type TileSize = 8 | 16 | 32
10
const tile: TileSize = 16

2. Intersection (ꡐ집합, &)

Intersect(μΈν„°μ„Ήμ…˜) : κ΅μ°¨ν•˜λ‹€[λ§Œλ‚˜λ‹€], (μ–΄λ–€ 지역을) κ°€λ‘œμ§€λ₯΄λ‹€, ꡐ집합

1
type student = {
2
name: string
3
score: number
4
}
5
6
type father = {
7
empolyeeId: number
8
work: () => void
9
}
10
11
// 학생 & 직μž₯인 νƒ€μž…μ„ λͺ¨λ‘ μž‘μ„±ν•΄μ•Όλ§Œ ν•˜λŠ” 경우
12
function internWork(μ§‘μ•ˆ: student & father) {
13
console.log(μ§‘μ•ˆ.name, μ§‘μ•ˆ.empolyeeId, μ§‘μ•ˆ.work())
14
}
15
16
internWork({
17
name: 'λ©”μ‹œ',
18
score: 189,
19
empolyeeId: 123,
20
work: () => {},
21
})

3. Union Type을 μ“Έ λ•Œ μ£Όμ˜ν•  점

λ…Όλ¦¬μ μœΌλ‘œ Unio νƒ€μž…μ€ OR, Intersection νƒ€μž…μ€ AND라고 μƒκ°ν•˜μ‹œλŠ” 뢄듀이 μžˆμ„ν…λ°, Interace와 같은 νƒ€μž…μ„ λ‹€λ£° λ•ŒλŠ” λ‹€μŒμ™€ 같은 논리적 사고λ₯Ό μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ•„λž˜ μ½”λ“œλ₯Ό λ³΄κ² μŠ΅λ‹ˆλ‹€.

1
interface Person {
2
name: string
3
age: number
4
}
5
interface Developer {
6
name: string
7
skill: string
8
}
9
10
// νŒŒλΌλ―Έν„° νƒ€μž…μ„ `Person`, `Developer` μΈν„°νŽ˜μ΄μŠ€μ˜ Union νƒ€μž…μœΌλ‘œ μ •μ˜
11
// νŒŒλΌλ―Έν„°μ˜ νƒ€μž…μ΄ `Person`도 되고 `Developer`도 λœλ‹€κ³  μƒκ°ν•΄μ„œ
12
// ν•¨μˆ˜ μ•ˆμ— ν•΄λ‹Ή μΈν„°νŽ˜μ΄μŠ€λ“€μ΄ μ œκ³΅ν•˜λŠ” `age`λ‚˜ `skill`λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€λΌκ³  생각할 수 있음
13
// κ·ΈλŸ¬λ‚˜ introduce() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” μ‹œμ μ— `Person` νƒ€μž…μ΄ μ˜¬μ§€ `Developer` νƒ€μž…μ΄ μ˜¬μ§€ μ•Œ μˆ˜κ°€ μ—†μŒ
14
// κ·Έλž˜μ„œ TSλŠ” μ–΄λŠ νƒ€μž…μ΄ λ“€μ–΄μ˜€λ“  간에 였λ₯˜κ°€ μ•ˆ λ‚˜λŠ” λ°©ν–₯으둜 νƒ€μž…μ„ 좔둠함
15
function introduce(someone: Person | Developer) {
16
someone.name // O 정상 λ™μž‘
17
someone.age // X νƒ€μž… 였λ₯˜
18
someone.skill // X νƒ€μž… 였λ₯˜
19
}

결과적으둜 introduce()μ•ˆμ—μ„œλŠ” λ³„λ„μ˜ **νƒ€μž… κ°€λ“œ(Type Guard)**λ₯Ό μ΄μš©ν•˜μ—¬ νƒ€μž…μ˜ λ²”μœ„λ₯Ό μ’νžˆμ§€ μ•ŠλŠ” 이상, κΈ°λ³Έμ μœΌλ‘œλŠ” Personκ³Ό Developer 두 νƒ€μž…μ— κ³΅ν†΅μ μœΌλ‘œ λ“€μ–΄μžˆλŠ” 속성인 name만 μ ‘κ·Όν•  수 있게 λ©λ‹ˆλ‹€.


4. Type Narrowing(νƒ€μž… 쒁히기)

ifλ¬Έ λ“±μœΌλ‘œ νƒ€μž…μ„ ν•˜λ‚˜λ‘œ μ •ν•΄μ£ΌλŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. νƒ€μž…μ΄ ν™•μ‹€ν•˜μ§€ μ•Šμ„ λ•Œ μƒκΈ°λŠ” λΆ€μž‘μš©μ„ λ§‰κΈ°μœ„ν•œ μž₯μΉ˜μž…λ‹ˆλ‹€.

Narrowing으둜 νŒμ •ν•΄μ£ΌλŠ” 문법듀

  • 쑰건문을 μ΄μš©ν•œ νƒ€μž…κ°€λ“œ
  • typeof νƒ€μž… κ°€λ“œ : typeof λ³€μˆ˜
  • in νƒ€μž… κ°€λ“œ : 속성λͺ… in 였브젝트 자료
  • instanceof νƒ€μž… κ°€λ“œ : μΈμŠ€ν„΄μŠ€ instanceof λΆ€λͺ¨

4.1 쑰건문을 μ΄μš©ν•œ νƒ€μž…κ°€λ“œ

1
type Animal = {
2
name: string
3
legs?: number
4
}
5
function addLeg(animal: Animal) {
6
// leg 속성이 undefinedκ°€ 될수 있기 λ•Œλ¬Έμ— νƒ€μž… μ—λŸ¬κ°€ λ°œμƒν•  수 있음
7
// leg 속성을 μ‚¬μš©ν•˜κΈ° 전에 truthy인지 ν™•μΈν•˜λ©΄ 됨
8
// λ³€μˆ˜μ—μ„œ nullκ³Ό undefinedλ₯Ό μ œμ™Έμ‹œν‚΄
9
if (animal.legs) {
10
animal.legs = animal.legs + 1
11
}
12
}

4.2 typeof νƒ€μž… κ°€λ“œ

1
function PlusOne(x: number | string) {
2
if (typeof x === 'number') return x + 1
3
else if (typeof x === 'string') return x + 1
4
else return 0
5
}

4.3 in νƒ€μž… κ°€λ“œ

1
interface Person {
2
firstName: string
3
surname: string
4
}
5
interface Organization {
6
name: string
7
}
8
9
type Contact = Person | Organization
10
11
function sayHello(contact: Contact) {
12
// 속성λͺ… in 였브젝트 자료
13
if ('firstName' in contact) {
14
console.log('Hello ' + contact.firstName)
15
}
16
}

4.4 instanceof νƒ€μž… κ°€λ“œ

1
class Person {
2
constructor(
3
public firstName: string,
4
public surname: string,
5
) {}
6
}
7
class Organisation {
8
constructor(public name: string) {}
9
}
10
type Contact = Person | Organisation
11
12
function sayHello(contact: Contact) {
13
console.log('Hello ' + contact.firstName)
14
// πŸ’₯ Property 'firstName' does not exist on type 'Contact'.
15
// πŸ’₯ contactκ°€ firstName 속성λ₯Ό μ—†λŠ” Organisation νƒ€μž…μΌ 수 있기 λ•Œλ¬Έ
16
}

μΈμŠ€ν„΄μŠ€ instanceof λΆ€λͺ¨λ₯Ό μ‚¬μš©ν•˜λ©΄, νŽΈν•©λ‹ˆλ‹€.

1
class Person {
2
constructor(
3
public firstName: string,
4
public surname: string,
5
) {}
6
}
7
class Organisation {
8
constructor(public name: string) {}
9
}
10
type Contact = Person | Organisation
11
12
function sayHello(contact: Contact) {
13
// μΈμŠ€ν„΄μŠ€ instanceof λΆ€λͺ¨
14
// if λ¬Έμ•ˆμ—μ„œ contact의 νƒ€μž…μ€ Person으둜 μ’ν˜€μ§(narrow)
15
if (contact instanceof Person) {
16
console.log('Hello ' + contact.firstName)
17
}
18
}