LHS_EffectiveTypescript_05 - YDP-SPLOUNGE-CLUB/typescript-study GitHub Wiki
νμ μ€ν¬λ¦½νΈκ° λνκΈ°λ₯Ό ν΅ν΄ μμμ νμ μ μΆλ‘ νλ λ²μ μ΄ν΄ν΄μΌ νλ€.
μ§μ λ λ¨μΌ κ°μ κ°μ§κ³ ν λΉ κ°λ₯ν κ°λ€μ μ§ν©μ μ μΆν΄μΌ νλ κ³Όμ μ λνκΈ°(widening) μ΄λΌ νλ€.
let λμ constλ₯Ό μ¬μ©νμ¬ λ μ’μ νμ μ΄ λλλ‘ νμ.
const x = 'x' // type is "x"
let vec = { x: 10, y: 20, z: 30 }
getComponent(vec, x) // OKκ·Έλ¬λ κ°μ²΄μ λ°°μ΄μ κ²½μ°μλ μ¬μ ν λ¬Έμ κ° λ¨μμλ€. λ°λΌμ κ°μ²΄μ κ²½μ° νλ²μ λ§λ€μ΄μΌ νλ€. (μμ΄ν 23)
μ± μμλ νμ μ€ν¬λ¦½νΈ κΈ°λ³Έ λμμ μ¬μ μνλ μΈκ°μ§ λ°©λ²μ μκ°νλ€.
- λͺ μμ νμ ꡬ문μ μ 곡νλ λ°©λ²
- νμ 체컀μ μΆκ°μ μΈ λ¬Έλ§₯μ μ 곡νλ λ°©λ²
- const λ¨μΈλ¬Έμ μ¬μ©νλ λ°©λ²
λμμ μν₯μ μ€ μ μλ λ°©λ²μΈ const, νμ ꡬ문, λ¬Έλ§₯, as constμ μ΅μν΄μ ΈμΌ νλ€.
const λ¨μΈλ¬Έκ³Ό λ³μ μ μΈμ μ°μ΄λ let, const μ νΌλνλ©΄ μλλ€. const λ¨μΈλ¬Έμ μ¨μ ν νμ 곡κ°μ κΈ°λ²μ΄λ€.
const v1 = {
x: 1,
y: 2,
} // Type is { x: number; y: number; }
const v2 = {
x: 1 as const,
y: 2,
} // Type is { x: 1; y: number; }
const v3 = {
x: 1,
y: 2,
} as const // Type is { readonly x: 1; readonly y: 2; }const λ¨μΈλ¬Έμ ν΅ν΄ μ΅λν μ’μ νμ μΌλ‘ μΆλ‘ νλ€.
λν λ°°μ΄μ νν νμ μΌλ‘ μΆλ‘ ν λμλ as constλ₯Ό μ¬μ©ν μ μλ€.
const a1 = [1, 2, 3] // Type is number[]
const a2 = [1, 2, 3] as const // Type is readonly [1, 2, 3]λΆκΈ°λ¬Έ μΈμλ μ¬λ¬ μ’ λ₯μ μ μ΄ νλ¦μ μ΄ν΄λ³΄λ©° νμ μ€ν¬λ¦½νΈκ° νμ μ μ’νλ κ³Όμ μ μ΄ν΄ν΄μΌ νλ€.
λΆκΈ°μμ μμΈλ₯Ό λμ§κ±°λ ν¨μλ₯Ό λ°ννμ¬ λΈλ‘μ λλ¨Έμ§ λΆλΆμμ λ³μμ νμ μ μ’ν μ μλ€.
const el = document.getElementById('foo') // Type is HTMLElement | null
if (!el) throw new Error('Unable to find #foo')
el // Now type is HTMLElement
el.innerHTML = 'Party Time'.blink()instanceof λ₯Ό μ¬μ©ν΄μ νμ μ μ’ν μ μλ€.
function contains(text: string, search: string | RegExp) {
if (search instanceof RegExp) {
search // Type is RegExp
return !!search.exec(text)
} search // Type is string
return text.includes(search)
}μμ±μ²΄ν¬λ‘λ νμ μ μ’ν μ μλ€.
interface A {
a: number
}
interface B {
b: number
}
function pickAB(ab: A | B) {
if ('a' in ab) {
ab // Type is A
} else {
ab // Type is B
}
ab // Type is A | B
}λ΄μ₯ν¨μλ₯Ό ν΅ν΄ νμ μ μ’ν μ μλ€.
function contains(text: string, terms: string | string[]) {
const termList = Array.isArray(terms) ? terms : [terms]
termList // Type is string[]
// ...}
}νκ·Έλ/ꡬλ³λ μ λμ¨κ³Ό μ¬μ©μ μ μ νμ κ°λλ₯Ό μ¬μ©νμ¬ νμ μ’νκΈ°μ κ³Όμ μ μννκ² λ§λ€ μ μλ€.
λ λ€λ₯Έ λ°©λ²μ 'νκ·Έ'λ₯Ό λΆμ΄λ λ°©λ²μ΄ μλ€.
interface UploadEvent {
type: 'upload'
filename: string
contents: string
}
interface DownloadEvent {
type: 'download'
filename: string
}
type AppEvent = UploadEvent | DownloadEvent
function handleEvent(e: AppEvent) {
switch (e.type) {
case 'download':
e // Type is DownloadEvent
break
case 'upload':
e // Type is UploadEvent
break
}
}μ΄ ν¨ν΄μ νκ·Έλ μ λμ¨ λλ ꡬλ³λ μ λμ¨ μ΄λΌκ³ λΆλ¦°λ€. λ§μ½ νμ μ€ν¬λ¦½νΈκ° νμ μ μλ³νμ§ λͺ»νλ€λ©΄, μλ³μ λκΈ° μν΄ μ»€μ€ν ν¨μλ₯Ό λμ ν μ μλ€.
function isInputElement(el: HTMLElement): el is HTMLInputElement {
return 'value' in el
}
function getElementContent(el: HTMLElement) {
if (isInputElement(el)) {
el // Type is HTMLInputElement
return el.value
}
el // Type is HTMLElement
return el.textContent
}μ΄ κΈ°λ²μ μ¬μ©μμ μνμ κ°λλ‘ λΆλ¦¬λ©°, λ°ν νμ μ΄ true μΌ κ²½μ° νμ 체컀μκ² λ§€κ°λ³μμ νμ μ μ’ν μ μλ€κ³ μλ €μ£Όλ μν μ νλ€.
μμ±μ μ κ°κ° μΆκ°νμ§ λ§κ³ νκΊΌλ²μ κ°μ²΄λ‘ λ§λ€μ΄μΌν©λλ€. μμ ν νμ μΌλ‘ μμ±μ μΆκ°νλ €λ©΄ κ°μ²΄ μ κ°({...a, ...b})λ₯Ό μ¬μ©νλ©΄ λλ€.
λ³μμ κ°μ λ³κ²½λ μ μμ§λ§ νμ μ μΌλ°μ μΌλ‘ λ³κ²½λμ§ μλλ€. μ¦ κ°μ²΄λ₯Ό μμ±ν λλ νλμ© μΆκ°ν기보λ€λ μ¬λ¬ μμ±μ ν¬ν¨ν΄μ νκΊΌλ²μ μμ±ν΄μΌ νμ μΆλ‘ μ μ 리νλ€.
const pt = {}
pt.x = 3
// ~ Property 'x' does not exist on type '{}'
pt.y = 4
// ~ Property 'y' does not exist on type '{}'interface Point {
x: number
y: number
}
const pt:Point = {
x: 3,
y: 4,
} // OKνΉμ κ°μ²΄ μ κ° μ°μ°μλ₯Ό ν΅ν΄ νκΊΌλ²μ λ§λ€μ΄ λΌ μ μλ€.
const pt = { x: 3, y: 4 }
const id = { name: 'Pythagoras' }
const namedPoint = { ...pt, ...id }
namedPoint.name // OK, type is stringλ³μΉμ νμ μ€ν¬λ¦½νΈκ° νμ μ μ’νλ κ²μ λ°©ν΄νλ€. λ°λΌμ λ³μμ λ³μΉμ μ¬μ©ν λλ μΌκ΄λκ² μ¬μ©ν΄μΌ νλ€..
const borough = { name: 'Brooklyn', location: [40.688, -73.979] }
const loc = borough.location;borough.location λ°°μ΄μ loc μ΄λΌλ λ³μΉ(alias)μ λ§λ€μλ€. λ³μΉμ κ°μ λ³κ²½νλ©΄ μλ μμ±κ°μμλ λ³κ²½λλ€.
λ³μΉμ λ¨λ°ν΄μ μ¬μ©νλ©΄ μ μ΄ νλ¦μ λΆμνκΈ° μ΄λ ΅λ€.
λΉκ΅¬μ‘°ν λ¬Έλ²μ μ¬μ©ν΄μ μΌκ΄λ μ΄λ¦μ μ¬μ©νλ κ²μ΄ μ’λ€.
interface Coordinate {
x: number
y: number
}
interface BoundingBox {
x: [number, number]
y: [number, number]
}
interface Polygon {
exterior: Coordinate[]
holes: Coordinate[][]
bbox?: BoundingBox
}
function isPointInPolygon(polygon: Polygon, pt: Coordinate) {
const { bbox } = polygon
if (bbox) {
const { x, y } = bbox
if (pt.x < x[0] || pt.x > x[1] || pt.y < x[0] || pt.y > y[1]) {
return false
}
}
// ...
}ꡬ쑰λΆν΄ν λΉμ ν΅ν΄μ μΌκ΄μ±μλ μ΄λ¦μ μ¬μ©νμ.
μ½λ°±λ³΄λ€λ νλ‘λ―Έμ€λ₯Ό μ¬μ©νλκ² μ½λ μμ±κ³Ό νμ μΆλ‘ λ©΄μμ μ 리νλ€.
μ΄μ λ λ€μκ³Ό κ°λ€.
- μ½λ°±λ³΄λ€λ νλ‘λ―Έμ€κ° μ½λλ₯Ό μμ±νκΈ° μ½λ€.
- μ½λ°±λ³΄λ€λ νλ‘λ―Έμ€κ° νμ μ μΆλ‘ νκΈ° μ½λ€.
κ°λ₯νλ©΄ νλ‘λ―Έμ€λ₯Ό μμ±ν기보λ€λ asyncμ awaitλ₯Ό μ¬μ©νλ κ²μ΄ μ’λ€. κ°κ²°νκ³ μ§κ΄μ μΈ μ½λλ₯Ό μμ±ν μ μκ³ λͺ¨λ μ’ λ₯μ μ€λ₯λ₯Ό μ κ±°ν μ μλ€.
κ·Έλ¬λ μΌλ°μ μΌλ‘λ νλ‘λ―Έμ€λ₯Ό μμ±ν기보λ€λ async/awaitλ₯Ό μ¬μ©νμ.
μ΄μ λ λ€μκ³Ό κ°λ€.
- μΌλ°μ μΌλ‘ λ κ°κ²°νκ³ μ§κ΄μ μΈ μ½λκ° λλ€.
- async ν¨μλ νμ νλ‘λ―Έμ€λ₯Ό λ°ννλλ‘ κ°μ λλ€.
// function getNumber(): Promise<number>
async function getNumber() {
return 42
}μ΄λ€ ν¨μκ° νλ‘λ―Έμ€λ₯Ό λ°ννλ€λ©΄ asyncλ‘ μ μΈνλ κ²μ΄ μ’λ€.
μ¦μ μ¬μ© κ°λ₯ν κ°μλ νλ‘λ―Έμ€λ₯Ό λ°ννλκ² μ΄μνκ² λ³΄μΌ μ μμ§λ§, μ€μ λ‘λ λΉλκΈ° ν¨μλ‘ ν΅μΌνλλ‘ κ°μ νλλ° λμμ΄ λλ€.