C.W.K.
Stream
Lesson 02 of 05 · published

`instanceof` 와 `in` Narrowing

~9 min · narrowing, instanceof, in, classes

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"Class 엔 instanceof. Property 존재엔 in. 둘 다 말한 거 정확히 narrow."

Class instance 용 `instanceof`

Runtime 의 x instanceof Foo 가 `x` 의 prototype 체인이 `Foo.prototype` 포함하는지 체크. TypeScript 가 이걸 narrowing 으로 읽어: `if` 안에서 `x` 가 `Foo` 타입. 밖에선 union 에서 `Foo` 뺀 거. 어떤 class — built-in (Date, Error, Array, Map) 또는 user-defined — 든 작동.

고전 사용: union 의 class-instance variant 구별. x: Date | stringif (x instanceof Date) 로 narrow 가능 — 안에선 `x.toISOString()`; 밖에선 `x.toUpperCase()`.

Property 존재 용 `in`

Runtime 의 'prop' in x 가 `x` 가 `'prop'` 이름의 property 가지는지 체크 (prototype 체인 어디든). TypeScript 가 이걸 narrowing 으로 읽어: `if` 안에서 `x` 가 union 의 `prop` 가진 variant. 밖에선 안 가진 variant.

`in` operator 가 variant 들이 공유 discriminator 필드 없을 때 모양에 narrow 하는 가장 깨끗한 방법. x: { name: string } | { id: number }if ('name' in x) 로 narrow 가능.

어느 거 선택할 때

instanceof: variant 가 class instance 일 때 (Date vs Error vs RegExp). Class 정체가 discriminator.

in: variant 가 공유 discriminator 없는 plain object 모양일 때. Property 존재가 discriminator.

typeof: primitive.

Discriminator equality: 모양이 literal 값의 `kind`/`type` 필드 공유할 때 — 가장 깨끗, 가장 명시적 옵션.

4개 narrowing operator 가 거의 모든 실제 case cover. 커스텀 type predicate (다음 lesson) 이 나머지 채워 — 단일 operator 가 표현할 수 없는 정교한 체크.

Code

class 엔 instanceof, 모양엔 in·typescript
// instanceof — class instance narrowing.
function stamp(x: Date | Error): string {
  if (x instanceof Date) {
    return x.toISOString();        // x: Date
  }
  return x.message;                // x: Error
}

// instanceof 가 user-defined class 와도 작동.
class NetworkError extends Error { constructor(public status: number) { super() } }
class TimeoutError extends Error { constructor(public elapsed: number) { super() } }

function handle(err: NetworkError | TimeoutError): string {
  if (err instanceof NetworkError) {
    return `HTTP ${err.status}`;   // err: NetworkError
  }
  return `Timed out after ${err.elapsed}ms`;  // err: TimeoutError
}

// `in` — property 존재 narrowing.
function printId(item: { id: number } | { name: string }) {
  if ('id' in item) {
    return item.id;                // item: { id: number }
  }
  return item.name;                // item: { name: string }
}

External links

Exercise

Date | Error | { id: number } 받고 문자열 표현 반환하는 serialize 함수 써. Date 와 Error 엔 instanceof, plain object 엔 in. Compiler 가 각 분기 narrow 하고 타입-specific method/property 접근 가능 확인.
Hint
Date → toISOString(). Error → message. Plain object 분기가 'id' in x{ id: number } 로 narrow (Date 와 Error 가 plain id 안 가져서).

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.