Strict 모드는 옵션 아냐
cwkPippa 의 모든 tsconfig.json 에 "strict": true. 협상 안 해. dogma 때문이 아니야. strict가 컴파일할 때 잡는 오류는 대개 새벽 2시에만 나타나서 사람 약 올리는 종류거든.
strictNullChecks 는 'cannot read property of undefined' 패밀리 잡아. noImplicitAny 는 sloppy 한 parameter 하나가 call graph 전체에 any 새는 거 막아. strictFunctionTypes 는 함수 파라미터 variance 를 정직하게 만들어.
Discriminated union 으로 server 메시지 모델링
backend의 SSE stream은 text delta, tool use, tool result, error, 마지막 done 같은 typed event를 보내. 이걸 하나의 discriminated union으로 모델링하면 TypeScript가 각 switch arm에서 type을 좁혀 줘. 새 event를 추가하고 case를 빠뜨린 자리도 exhaustive check로 드러나.
Generic hook — inference 안 잃고 typed
custom hook은 generic을 받아서 caller의 type 정보를 보존해. useFetch<T>()처럼 반환 계약이 드러나는 편이, 아무 값이나 내놓는 useFetch()보다 훨씬 정직해.
any는 type 계약을 지워 버려. as any에 손이 갈 때는 멈추고 진짜로 원하는 contract가 뭔지 생각해. 경계에서 아직 모르는 값이라면 unknown으로 받고 runtime guard로 좁혀. 귀찮아도 거짓 확신보단 낫지.
Strict typing의 목적은 타입 체조가 아니야. server가 보내는 값, UI가 믿는 값, 사용자가 실제로 보는 값 사이에 검문소를 세우는 거야. 특히 SSE처럼 여러 event가 한 통로로 흐를 땐 "대충 이런 모양"이라는 믿음이 가장 위험해. 네트워크 경계에서 검증하고, union 안으로 들어온 뒤에는 compiler가 끝까지 따라오게 해. 그러면 오류 처리는 예외적인 땜질이 아니라 모델의 한 가지 정상 분기가 돼.