"대부분 TypeScript 프로그래머가 손으로 절대 타이핑 안 할 primitive 2개 — 근데 나타나면 둘 다 알아봐야 해."
symbol — 고유 보장 식별자
symbol 은 고유 보장된 primitive 값. 같은 설명으로 Symbol() 두 번 호출하면 다른 symbol 두 개 만들어. 다른 사람 key 와 충돌 없이 object 에 데이터 붙여야 할 때 object property key 로 가장 흔히 써.
built-in well-known symbol 통해 가장 자주 만나 — Symbol.iterator, Symbol.asyncIterator, Symbol.toPrimitive, 등등. 이게 JavaScript 의 iteration protocol, primitive coercion, 다른 meta-behavior 가 너의 object 에 hook 하는 법. for (const x of obj) 써본 적 있으면, 그 loop 가 내부에서 obj[Symbol.iterator]() 호출.
자기 symbol 선언 (const TAG = Symbol('Tag')), private 같은 property key 로 사용, 심지어 unique symbol 타입으로 타이핑 가능. 근데 일상 TypeScript 가 직접 거의 안 만져 — 소비하는 library API 의 type annotation 에 가장 자주 나타나.
bigint — 임의 정밀도 integer
JavaScript 의 number 는 64-bit double, 즉 ±2^53 넘는 integer 산술이 정밀도 잃어. bigint 가 해결: 어떤 크기 산술이든 다루는 임의 정밀도 integer 타입, trade-off 는 명시적 변환 없이 number 와 못 섞어.
Bigint literal 은 n suffix 로 써: const big = 9007199254740993n. 또는 BigInt(value) 호출. 두 bigint 사이 산술 연산자 정상 작동 (big * 2n), 근데 타입 섞기 throw: big + 1 이 runtime 에 TypeError. 옳게 annotate 했으면 TypeScript 가 compile 시점에 잡아.
Bigint 쓸 때: 나노초 timestamp, Number.MAX_SAFE_INTEGER 초과하는 ID (64-bit 식별자 쓰는 시스템의 DB row ID), 암호학, float 에러 피해야 하는 금융 계산.
string, number, boolean 써. symbol 과 bigint 는 특화 tool — 알아봐, 자기 문제 나타날 때 써, 그 외엔 toolbox 에 둬.Wrapper object 존재 (그리고 여전히 피해야 함)
Big three 와 같은 소문자-vs-대문자 규칙: : symbol 이 primitive, : Symbol 은 wrapper-object constructor 타입. : bigint primitive, : BigInt wrapper. 항상 소문자.