
사람이 무언가를 집중해서 바라보다 보면, 어느샌가 주변부가 흐려지고 가끔은 집중하고 있던 그 대상조차 보이지 않게 된다. 처음엔 분명하게 인식되던 경계가 서서히 사라지고, 오히려 애써 무시했던 주변이 본질을 가릴 때도 있다. 잘 보려 애쓰는 행위가, 역설적으로 시야를 좁히는 순간이다.
개발에서도 비슷한 순간이 찾아온다. 타입을 정교하게 다듬고, 설계를 촘촘하게 만드는 데 집중하다 보면 어느새 전체 맥락을 잃어버린다. 엄밀함이라는 이름 아래, 타입 그 자체에 집착하게 되고, 그 타입이 놓인 현실적인 맥락은 시야에서 밀려난다. 나는 그 맹목의 순간을 몇 번이나 지나왔다.
타입스크립트를 사용하다 보면 “더 정확한 타입”, “더 안전한 설계”라는 목표는 언제나 옳아 보인다. 실제로 많은 버그를 사전에 차단해주고, 코드의 의도를 명확히 드러내는 데에도 큰 도움이 된다. 문제는 그 정확함이 목적이 되는 순간부터 시작된다.
타입을 정교하게 만들기 위해 복잡한 제네릭을 쌓고, 모든 경우의 수를 타입 레벨에서 봉쇄하려고 하다 보면, 어느새 질문이 바뀐다.
“이 코드는 현실에서 어떻게 쓰일까?”가 아니라
“이 타입은 논리적으로 완벽한가?”가 중심이 된다.
그 순간부터 설계는 점점 현실과 멀어진다.
개발에서의 엄밀함은 분명 중요하다. 하지만 그 엄밀함은 언제나 맥락 위에 놓여야 한다. 타입은 코드를 설명하는 수단이지, 그 자체로 완결된 세계가 아니다. 타입이 현실을 설명하지 못하는 순간, 타입을 잘못 설계한 것이 아니라 타입을 바라보는 시야를 잘못 설정한 것일지도 모른다.
이후 설계를 수정하면서 나는 한 가지 원칙을 다시 세웠다. 설계는 “완벽하게 막는 것”보다, “잘못되었을 때 드러나는 것”이 더 중요하다는 점이다. 모든 경우를 사전에 봉쇄하려 하기보다는, 현실적인 사용을 자연스럽게 수용하고, 잘못된 조합이 명확하게 실패하도록 만드는 쪽이 더 건강한 구조일 수 있다.
아이러니하게도, 그렇게 한 발 물러서서 설계를 다시 보니 이전보다 타입은 더 단순해졌고, 구조는 오히려 더 단단해졌다. 시야를 넓히자, 그제야 정말로 잘 보이기 시작했다.
개발자는 종종 “더 잘 보기 위해” 눈을 좁힌다. 하지만 집중이 맹목이 되는 순간, 우리는 중요한 것을 놓친다. 타입이든, 아키텍처든, 추상화든 마찬가지다. 잘 만든다는 명분 아래, 우리가 보고 있는 것이 무엇인지 스스로에게 묻지 않으면, 설계는 쉽게 현실과 어긋난다.
요즘 나는 코드보다도, 내가 어디를 보고 있는지를 더 자주 점검하려 한다. 엄밀함에 취해 시야를 좁히고 있지는 않은지, 논리적으로 완벽하다는 이유로 현실을 외면하고 있지는 않은지. 그 질문을 던지는 것만으로도, 설계는 조금 더 사람을 닮아간다.
더 읽어보기
2025.09.14
Loose Autocomplete
프로그래밍을 하다 보면 개발자가 의도한 선택지를 에디터가 자동완성으로 얼마나 잘 안내해 주느냐가 개발 경험에 큰 영향을 미친다는 사실을 자주 체감하게 된다. 특히 문자열 기반의 옵션을 다룰 때는 이 차이가 더욱 극명하게 드러난다.예를 들어 HTTP 메서드를 표현할 때 "GET" | "P…
2025.04.06
재귀 조건부 타입에서의 추론 컨텍스트 손실
타입스크립트에서는 조건부 타입의 분배 과정에서도 타입 추론 컨텍스트가 유지된다. 이 특성 덕분에 단순한 분기 수준을 넘어, 상당히 복잡한 조건부 타입에서도 개발자가 의도한 방향으로 타입 추론을 유도할 수 있다. 실제로 이러한 특성은 고급 유틸리티 타입을 설계할 때 매우 강력한 도구로 작…
2025.03.28
유틸리티 타입 IsInRange
프론트엔드 개발을 하다 보면 컴포넌트의 props로 number 타입을 받을 때가 많다. 하지만 단순히 number 타입만 지정하면 값의 범위를 제한할 수 없다는 점이 아쉽다. 예를 들어, 페이지네이션의 currentPage는 1 이상의 값만 허용해야 하고, 슬라이더의 value는 최소…
2025.03.11
Equal but not Equal
TypeScript를 사용하다 보면, 겉보기에는 동일해 보이지만 실제로는 다르게 평가되는 타입을 마주치는 경우가 있다. 특히 객체 타입과 인터섹션 타입을 함께 다룰 때 이런 차이가 분명하게 드러난다.다음 두 타입을 살펴보자.type A = { x: string; y: string };…
2026.04.11
Trie 자료구조
문자열 데이터를 다룰 때 단순히 “이 단어가 있나?”만으로는 부족한 순간이 있다. 자동 완성처럼 특정 접두사로 시작하는 후보를 모아야 할 때도 있고, 어떤 키에 값을 두고 빠르게 찾고 싶을 때도 있다. 이럴 때 가장 자연스럽게 떠올릴 수 있는 자료구조가 바로 Trie이다.Trie는 무엇…
2026.03.19
Streams API 부록 2. 왜 이미지는 위에서 아래로 나타날까
웹 페이지에서 이미지를 로드할 때 흥미로운 장면을 종종 볼 수 있다. 이미지가 한 번에 완전히 나타나는 것이 아니라, 위에서 아래로 조금씩 채워지면서 나타나는 경우가 있기 때문이다. 특히 네트워크가 느리거나 이미지가 큰 경우 이런 현상이 더 분명하게 보인다. 마치 이미지가 위쪽부터 스캔…
2026.03.19
Streams API 부록 1. HTTP 다운로드 진행률은 어떻게 계산될까
파일을 다운로드할 때 가끔 몇 퍼센트 진행되었는지 혹은 진행 막대(progress bar)가 조금씩 채워지는 모습을 볼 수 있다. 그런데 모든 다운로드가 이런 식으로 진행률을 보여 주는 것은 아니다. 어떤 다운로드는 퍼센트가 표시되지만, 어떤 경우에는 진행 막대 없이 로딩 스피너만 계속…
2026.03.13
Streams API 4. 왜 모든 언어에는 Stream API가 존재할까
Streams API를 공부하다 보면 묘한 기시감을 느끼게 된다. JavaScript에서 ReadableStream, WritableStream, TransformStream을 살펴보고 있는데, 어딘가 낯설지 않다. Java를 써 본 사람이라면 InputStream, OutputStre…
댓글
댓글을 불러오는 중...