연재
번역 키를 컴파일 타임에 잡기
번역 키를 그냥 문자열이 아니라 타입으로 다뤄, 오타·미정의 키를 컴파일 타임에 잡아가는 과정.
6편
-
번역 키를 컴파일 타임에 잡기 #1 — TypeScript는 언제 무엇을 하는가
t('user.profile.title')의 오타는 왜 컴파일도 테스트도 다 통과하고 런타임에야 조용히 터질까. 그걸 타입만으로 잡고 싶어서, 먼저 TypeScript가 언제 무엇을 하는지 — 컴파일·실행 모델과 타입 소거부터 다시 봤다.
-
번역 키를 컴파일 타임에 잡기 #2 — 왜 조용히 터지나, 그리고 왜 개발 단계에서 잡아야 하나
번역 키 t('user.profile.title'), 딱 한 글자 잘못 쳤을 뿐인데 컴파일도 CI도 다 통과했다. 그런데 프랑스어 화면엔 영어가 떠 있다. 왜 이런 버그는 런타임에야 조용히 드러날까 — 그리고 나는 이걸 어디서 잡았어야 했을까.
-
번역 키를 컴파일 타임에 잡기 #3 — JSON을 타입으로, 도구 없이 declare module로 키 잠그기
번역 키를 타입으로 잠그려고 코드 생성기부터 떠올렸는데, 막상 해보니 내가 직접 짠 건 열 줄 남짓이었다. 중첩 키 평탄화 같은 어려운 부분은 i18next 타입이 이미 다 해두고 있었다.
-
번역 키를 컴파일 타임에 잡기 #4 — 타입을 집합으로 보기, i18next 타입을 읽는 법
#3에서 keyof·조건부 타입·템플릿 리터럴을 "썼지만" 왜 동작하는지는 파고들지 않았다. '타입은 값의 집합이다' 한 문장으로 그 밑바닥을 꿰고, i18next의 실제 타입 한 줄을 직접 읽어냈다.
-
번역 키를 컴파일 타임에 잡기 #5 — JS 모듈 시스템, 모듈이냐 스크립트냐
#3에서 declare module 한 줄로 번역 키를 잠갔는데, 그게 왜 아무도 import 안 해도 프로그램 전역에 퍼지는지는 안 풀렸다. 그걸 이해하려고 TypeScript를 잠깐 내려놓고 그 밑 JS 모듈 시스템으로 내려갔다 — 모듈이냐 스크립트냐를 누가 정하고, ESM과 CommonJS는 왜 다른가.
-
번역 키를 컴파일 타임에 잡기 #6 — 남의 라이브러리 타입을 내 코드에서 확장하기, module augmentation
#3에서 declare module 한 줄로 번역 키를 잠갔는데, 그게 왜 아무도 import 안 해도 프로그램 전역에 퍼지는지가 남아 있었다. i18next의 빈 interface를 채우는 module augmentation을 밑바닥까지 파고, barrel export가 왜 다른 앱까지 타입을 오염시키는지까지 내려갔다.