Null/undefined 는 "값이 없음"이라는 정보를 담지 못하는 가장 빈약한 표현. 타입에서 nullable 을 명시적으로 분리하고, 언래핑 지점을 명확히 만들어라.
📖 핵심 개념
Tony Hoare가 "the billion dollar mistake" 라고 부른 null 참조 문제. 모던 언어들은 다음 중 하나로 대응:
타입 시스템에서 nullable 분리: TypeScript T | null, Kotlin T?, Swift T?
Optional 타입: Rust Option<T>, Haskell Maybe a
Strict mode: TS의 strictNullChecks, Kotlin 디폴트, Swift 디폴트
핵심은 "이 값은 없을 수 있다"를 타입이 명시적으로 표현하고 컴파일러가 강제하는 것.
💻 코드 패턴
1. nullable 명시 (TypeScript with strictNullChecks)
// ❌ 모호함 — name 이 항상 있는지 가끔 없는지 모름
functiongreet(user:{name: string}){return`Hi, ${user.name}`;}// ✅ 명시
functiongreet(user:{name: string|null}){if(user.name===null)return'Hi, friend';return`Hi, ${user.name}`;}
2. Optional Chaining + Nullish Coalescing
// 깊은 경로 안전 접근
constcity=order?.shipping?.address?.city??'Unknown';// ❌ 주의: || 는 falsy("" / 0) 도 fallback 으로 처리
constport=config.port||3000;// port가 0이면 3000 됨!
constport=config.port??3000;// null/undefined 만 fallback ✓
복잡한 변환 체인이 많을 때만 도입. 단순한 T | null 로 충분한 경우엔 over-engineering.
5. Non-null assertion (!) 의 좁은 사용
constel=document.getElementById('root')!;// OK if you control the HTML
// ❌ 위험
functionfindUser(id: string){returnusers.find(u=>u.id===id)!;// 못 찾으면 런타임 사고
}// ✅
functionfindUser(id: string):User{constu=users.find(u=>u.id===id);if(!u)thrownewNotFoundError(id);returnu;}