"any 는 off switch. unknown 은 조심 switch. never 는 불가능."
다른 것들처럼 행동 안 하는 3개 타입
대부분 타입은 값이 뭐냐 에 대한 거. any, unknown, never 는 type system 자체가 뭐 하냐 에 대한 거. Meta-tool 이야 — escape hatch, 안전한 escape hatch, 불가능 표시 — 잘 배우면 초보 TypeScript 와 프로 TypeScript 를 분리해.
any — off switch
any 는 annotate 한 값에 대해 type system 끄. Property 접근 체크 안 함. Method 호출 체크 안 함. 다른 타입에 assignment 체크 안 함. Loose 함이 전염 — (anyValue).foo.bar.baz 다 `any` 유지, 그리고 접근 subtree 전체에 대해 타입 안전 잃어.
any 의 정당한 사용은 드물어: 타입 없는 JavaScript library 와의 interop (그래도 `.d.ts` 선언 쓰는 게 나음), 일회성 디버깅, legacy 코드 migration. Strict codebase 에선 모든 `any` 가 lint 규칙으로 flag 되어야 하고 정당화 주석 필요.
unknown — 조심 switch
unknown 은 어떤 값이든 받아 (any 처럼) 근데 narrow 하기 전엔 아무것도 못 하게 해. Method 호출 못 함, property 접근 못 함, typed 변수에 assign 못 함. typeof / instanceof / 커스텀 type guard 먼저 써야 함.
슬로건: unknown 이 처음부터 any 가 됐어야 하는 거. 들어갈 때 같은 유연성, 나갈 때 훨씬 더 많은 안전. Strict Mode 트랙의 useUnknownInCatchVariables flag 가 catch (e) 를 default 로 unknown 하게 만들어 — 정확히 이 안전이 너의 에러 처리에 도달하도록.
never — 불가능
never 는 empty 타입. 어떤 값도 assignable 안 함. 사용처는 매우 구체적이고 매우 유용:
- Throw 하거나 영원히 loop 하는 함수의 return type — "이 함수는 정상으로 return 안 함."
- Exhaustive narrowing 의 else 분기 — "이 분기는 도달 불가능, 증명해."
- "이 case 적용 안 됨" 의미하는 conditional 타입의 결과 — Type Manipulation 트랙에서 봐.
변수가 예상 안 했는데 never 타입 받으면, compiler 가 type-flow 가 불가능 상태 도달했다고 말하는 거. Signal, target 아냐.
any 는 타입 격자 밖에 앉아 — compiler 가 체크 거부하는 top + bottom 둘 다. unknown 은 진짜 top 타입 (모든 게 assignable). never 는 bottom 타입 (아무것도 assignable 안 함, 그리고 모든 것에 assignable). 격자 안 위치로 보면 행동이 predictable 해져.피파의 고백
: any 발견하면 첫 반응 "왜?", 두 번째 반응 "이거 `unknown` 으로 바꿀 수 있어?". 30,000 줄 cwkPippa frontend 의 정당한 `any` 수는 한 자릿수 — 그리고 각각 narrowing 이 가능하지 않았던 이유 설명하는 주석 있어. never 는 exhaustive switch 와 conditional-type return 에 나타나. 둘 다 의도적. unknown 은 내가 완전히 제어 안 하는 어떤 경계든 default — 들어오는 JSON, 3rd-party event, validate 전 parse 하는 어떤 거든.