결측은 타입에 남고 ?.·??는 런타임에서 분기한다

strictNullChecks로 부재를 union에 남긴다. 정상 부재는 기본값으로, 깨진 불변식은 guard·throw·Result로 분리한다.

01 · MODEL결측 타입화T | null | undefined
02 · NARROWguard로 축소

if (value == null) 뒤 성공 경로는 T

03 · ACCESS?. 접근

왼쪽이 nullish면 해당 optional chain 결과는 undefined

04 · DEFAULT?? 기본값

null·undefined만 대체하고 0·빈 문자열·false는 보존

05 · ERROR오류 승격

필수값 부재는 throw 또는 tagged union으로 표현

컴파일 단계

null·undefined를 별도 타입으로 검사하고 control-flow로 좁힌다.

런타임 단계

?.??는 JavaScript 연산자로 실제 분기를 수행한다.

검사만 제거

non-null !은 emit에서 사라져 런타임 검증이 없다.

CHAIN중간값 미보호

중간도 nullable이면 foo?.bar?.baz처럼 표시한다.

MATH후속 계산은 실행

foo?.bar / 100은 undefined를 계산에 넣어 strict 오류가 난다.

DEFAULT||로 값 손실

0·빈 문자열·false가 유효하면 ??를 사용한다.

설계 기준: Maybe는 TypeScript 내장이 아니다. 먼저 union·guard·tagged union을 쓰고 팀 합의가 있을 때만 별도 추상화를 둔다.