"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 | string 이 if (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` 필드 공유할 때 — 가장 깨끗, 가장 명시적 옵션.