여러 해 동안 Python/JavaScript로 웹과 로보틱스 소프트웨어를 개발하고 유지보수하며 배운 점을 정리했음
타입은 명시하지 않아도 존재하며, 명시하지 않으면 결국 머릿속에만 존재하게 됨
하지만 머리는 휘발성이 강하고 다른 사람이 접근하기 어려움
그래서 타이핑은 훌륭한 문서화 수단임
JSDoc과 TypeScript는 타입을 표현하는 표준 형식이며, 둘 다 장단점이 있음
중요한 건 일관성과 예측 가능성 있게 타입을 정의하는 것임
타입 체커는 “그럼 증명해봐”라고 말하는 컴퓨터의 방식임
모든 프로그램이 같은 수준의 증명을 필요로 하진 않으며, 과도한 증명은 낭비가 될 수 있음
그래서 나는 필요한 만큼만 “증명할 수 있는” 언어를 선호함
“머릿속에만 있는 정보는 휘발성이 강하다”는 말에 완전히 공감함
특히 ‘다른 사람’에는 미래의 나 자신도 포함됨이라는 걸 일하면서 절실히 배웠음
Rust는 “prove it” 철학의 대표로 알려져 있지만, 실제로는 그렇지 않다고 생각함
Rust는 unsafe, Arc, clone 같은 방식으로 제약을 완화할 수 있지만, 그 대신 어떤 제약이 증명되지 않았는지를 명확히 선택하게 함
반면 “증명하지 않아도 되는” 언어는 내부적으로 어떤 접근을 택했는지 알기 어려움
Rust의 접근은 초반에는 Python처럼 느슨하게 쓸 수 있지만, 이후 가독성과 확장성에서 훨씬 유리함
JSDoc과 TypeScript가 동일한 목적을 가진다는 점에 동의함
특정 도구를 옹호하려는 의도는 아니었고, 단지 둘 다 타입 시스템의 표현 방식이라는 점을 강조하고 싶었음
25년 전 대학 시절에 이미 이 교훈을 배웠음 정적 타이핑 언어가 팀 프로젝트에서 훨씬 다루기 쉬웠고, 지금도 가능하면 정적 타입을 선호함
“타입은 항상 존재한다”는 말에는 동의하지만, C#처럼 타입을 명시해야 하는 언어는 Ruby보다 훨씬 많은 작업이 필요함
기존 JS 라이브러리에 나중에 추가된 TypeScript 타입 정의를 보면 복잡성이 엄청남
잘못된 타입 하나로도 전체 컴파일이 깨질 수 있음
결국 동적 언어는 ‘스스로 책임지는’ 방식으로 써야 함
나는 빌드 스텝 없이 JavaScript로 만들 수 있는 모든 것을 좋아함
현대 HTML/CSS와 Web Components, 그리고 JSDoc 조합은 과소평가되어 있음
모두에게 맞진 않지만, 충분히 현대적인 프런트엔드 스택 후보라고 생각함
이제 Node 24부터는 TypeScript도 빌드 스텝 없이 실행 가능함
빌드 스텝이 없는 접근의 매력은 이해하지만, 실제로는 의존성 관리가 복잡해짐
HMR 같은 기능 덕분에 빌드 스텝의 비용도 많이 줄어듦
지난 10년간 실제로 배포된 JS 코드를 직접 쓴 적이 없음
항상 Vite나 Webpack을 거치기 때문에 빌드 없는 JS의 장점은 체감되지 않음
Web Components는 만들기 꽤 고통스러움
복잡한 컴포넌트를 쉽게 만드는 방법이 있었으면 좋겠음
HTML+CSS+JSDoc 조합의 장점은 브라우저 개발자 도구와의 자연스러운 통합임
네트워크 요청 추적, 소스 코드로 바로 이동, 브레이크포인트 설정 등 디버깅이 훨씬 직관적임
규모가 커질수록 이런 환경이 큰 도움이 됨
SPA가 유행하던 시절, JSDoc은 타입 관리의 구세주였음
이후 Google Closure Compiler가 등장해 JSDoc 기반 타입 안전성을 제공했고, TypeScript가 자체 문법과 함께 (TS)JSDoc을 지원함
커뮤니티는 결국 TypeScript를 선택했고 Closure Compiler는 사라짐
그래서 (TS)JSDoc은 MS가 Google과 경쟁하던 시절의 유물로 남음
지금은 TS가 제네릭, Enum, 유틸리티 타입, Vitest 타입 테스트, 타입가드 등 훨씬 많은 기능을 제공함
나는 TS와 JSDoc을 함께 씀 — TS는 코드용, JSDoc은 문서용 (@link, @see, @deprecated, @example 등)
실제로 현대 JSDoc은 TypeScript 언어 서비스를 사용함
제네릭, 유틸리티 타입, 타입가드, 정규식 파싱 등 대부분의 TS 기능을 JSDoc에서도 활용 가능함
개인 프로젝트에서 제네릭을 포함해 전부 JSDoc으로 구현해봤음
위 주장은 사실이 아님
(TS)JSDoc이 과거의 유물이라는 건 잘못된 정보이므로 확인 없이 퍼뜨리지 말아야 함
이 글 자체가 바로 그 주장에 대한 직접적인 반박임
JSDoc으로 표현할 수 없는 타입이 많다고 하지만, Flow처럼 전체 언어 접근이 가능했다면 좋았을 것 같음
TypeScript도 그렇게 할 수 있었는데 왜 안 했는지 모르겠음
구체적인 예시가 있다면 듣고 싶음
나도 예전엔 그렇게 생각했지만, 프로젝트를 JSDoc으로 리팩터링하면서 생각이 바뀜
JSDoc에서도 @template으로 제네릭 슬롯을 정의할 수 있음
예:
TypeScript의 타입 시스템은 튜링 완전(Turing complete) 하므로 사실상 무한한 표현력을 가짐 관련 링크
JSDoc으로 작성된 패키지는 CMD/CTRL 클릭 시 실제 코드로 이동할 수 있어서 개발자 경험이 좋음
이건 에디터 설정으로도 커스터마이징 가능함
사실 TypeScript에서도 동일하게 작동함
5년 전 밋업에서 어떤 발표자가 “TypeScript가 싫다면 JSDoc이 대안”이라고 말했음
나는 그게 결국 둘 다 TypeScript라고 설명했지만, 내 상사는 믿지 않았음
차이는 문법의 압축도(syntax compression) 정도라고 생각함
“JSDoc도 결국 TypeScript다”라는 말은 절반만 맞음
JSDoc과 TS는 모두 타입을 명시적으로 표현하지만, TS 문법이 훨씬 강력함
그래도 JS 환경을 유지하면서 타입 도구의 혜택을 얻고 싶은 사람에게는 JSDoc이 좋은 선택임
반론으로, JSDoc은 TypeScript가 아님 @typedef로 정의한 타입은 자동으로 export되며, 이를 제어할 방법이 없음 관련 이슈
이 때문에 라이브러리 개발 시 IntelliSense가 어지럽게 노출되어 불편했음
Web Components에는 JSDoc이 꽤 잘 맞음
“my-component.js” 파일을 그대로 복사해도 빌드 없이 동작함
하지만 대형 프로젝트에서는 TS 문법을 선호함
기술적으로는 맞는 지적이지만, @import를 조절하면 대부분 해결 가능함
“JSDoc은 TypeScript의 대안이 아니다”라는 주장에 동의함
JSDoc도 정적 분석을 제공하지만 빌드 스텝이 없음 Node 공식 문서 참고
내부적으로는 여전히 빌드 스텝이 존재함
하지만 JSDoc 기반 TS는 브라우저에서도 작동함
나는 개인적으로 TS 문법의 가독성을 선호하며, swc 같은 도구로 타입 제거 속도도 충분히 빠름
다만 이 기능은 Node 환경에 한정되어 있고 브라우저에서는 동작하지 않음
TypeScript가 다른 대안들을 제치고 승리한 이유는, 새로운 언어가 아니라 타입 체커로 남았기 때문임
초기에 방향이 다소 흔들렸지만, 적절히 수정했고 지금은 대부분의 코드에서 enums조차 잘 쓰지 않음
VSCode에서는 “TypeScript: Prefer Go To Source Definition” 설정을 켜면 실제 소스로 이동 가능함
또한 tsconfig에 declarationMap: true를 추가하면 더 정확하게 작동함
나는 거의 항상 cmd+click 시 소스 보기를 선호함
Hacker News 의견들
여러 해 동안 Python/JavaScript로 웹과 로보틱스 소프트웨어를 개발하고 유지보수하며 배운 점을 정리했음
타입은 명시하지 않아도 존재하며, 명시하지 않으면 결국 머릿속에만 존재하게 됨
하지만 머리는 휘발성이 강하고 다른 사람이 접근하기 어려움
그래서 타이핑은 훌륭한 문서화 수단임
JSDoc과 TypeScript는 타입을 표현하는 표준 형식이며, 둘 다 장단점이 있음
중요한 건 일관성과 예측 가능성 있게 타입을 정의하는 것임
타입 체커는 “그럼 증명해봐”라고 말하는 컴퓨터의 방식임
모든 프로그램이 같은 수준의 증명을 필요로 하진 않으며, 과도한 증명은 낭비가 될 수 있음
그래서 나는 필요한 만큼만 “증명할 수 있는” 언어를 선호함
특히 ‘다른 사람’에는 미래의 나 자신도 포함됨이라는 걸 일하면서 절실히 배웠음
Rust는 unsafe, Arc, clone 같은 방식으로 제약을 완화할 수 있지만, 그 대신 어떤 제약이 증명되지 않았는지를 명확히 선택하게 함
반면 “증명하지 않아도 되는” 언어는 내부적으로 어떤 접근을 택했는지 알기 어려움
Rust의 접근은 초반에는 Python처럼 느슨하게 쓸 수 있지만, 이후 가독성과 확장성에서 훨씬 유리함
특정 도구를 옹호하려는 의도는 아니었고, 단지 둘 다 타입 시스템의 표현 방식이라는 점을 강조하고 싶었음
정적 타이핑 언어가 팀 프로젝트에서 훨씬 다루기 쉬웠고, 지금도 가능하면 정적 타입을 선호함
기존 JS 라이브러리에 나중에 추가된 TypeScript 타입 정의를 보면 복잡성이 엄청남
잘못된 타입 하나로도 전체 컴파일이 깨질 수 있음
결국 동적 언어는 ‘스스로 책임지는’ 방식으로 써야 함
나는 빌드 스텝 없이 JavaScript로 만들 수 있는 모든 것을 좋아함
현대 HTML/CSS와 Web Components, 그리고 JSDoc 조합은 과소평가되어 있음
모두에게 맞진 않지만, 충분히 현대적인 프런트엔드 스택 후보라고 생각함
HMR 같은 기능 덕분에 빌드 스텝의 비용도 많이 줄어듦
항상 Vite나 Webpack을 거치기 때문에 빌드 없는 JS의 장점은 체감되지 않음
복잡한 컴포넌트를 쉽게 만드는 방법이 있었으면 좋겠음
네트워크 요청 추적, 소스 코드로 바로 이동, 브레이크포인트 설정 등 디버깅이 훨씬 직관적임
규모가 커질수록 이런 환경이 큰 도움이 됨
SPA가 유행하던 시절, JSDoc은 타입 관리의 구세주였음
이후 Google Closure Compiler가 등장해 JSDoc 기반 타입 안전성을 제공했고, TypeScript가 자체 문법과 함께 (TS)JSDoc을 지원함
커뮤니티는 결국 TypeScript를 선택했고 Closure Compiler는 사라짐
그래서 (TS)JSDoc은 MS가 Google과 경쟁하던 시절의 유물로 남음
지금은 TS가 제네릭, Enum, 유틸리티 타입, Vitest 타입 테스트, 타입가드 등 훨씬 많은 기능을 제공함
나는 TS와 JSDoc을 함께 씀 — TS는 코드용, JSDoc은 문서용 (@link, @see, @deprecated, @example 등)
제네릭, 유틸리티 타입, 타입가드, 정규식 파싱 등 대부분의 TS 기능을 JSDoc에서도 활용 가능함
개인 프로젝트에서 제네릭을 포함해 전부 JSDoc으로 구현해봤음
(TS)JSDoc이 과거의 유물이라는 건 잘못된 정보이므로 확인 없이 퍼뜨리지 말아야 함
JSDoc으로 표현할 수 없는 타입이 많다고 하지만, Flow처럼 전체 언어 접근이 가능했다면 좋았을 것 같음
TypeScript도 그렇게 할 수 있었는데 왜 안 했는지 모르겠음
나도 예전엔 그렇게 생각했지만, 프로젝트를 JSDoc으로 리팩터링하면서 생각이 바뀜
JSDoc에서도
@template으로 제네릭 슬롯을 정의할 수 있음예:
관련 링크
JSDoc으로 작성된 패키지는 CMD/CTRL 클릭 시 실제 코드로 이동할 수 있어서 개발자 경험이 좋음
5년 전 밋업에서 어떤 발표자가 “TypeScript가 싫다면 JSDoc이 대안”이라고 말했음
나는 그게 결국 둘 다 TypeScript라고 설명했지만, 내 상사는 믿지 않았음
JSDoc과 TS는 모두 타입을 명시적으로 표현하지만, TS 문법이 훨씬 강력함
그래도 JS 환경을 유지하면서 타입 도구의 혜택을 얻고 싶은 사람에게는 JSDoc이 좋은 선택임
반론으로, JSDoc은 TypeScript가 아님
@typedef로 정의한 타입은 자동으로 export되며, 이를 제어할 방법이 없음관련 이슈
이 때문에 라이브러리 개발 시 IntelliSense가 어지럽게 노출되어 불편했음
“my-component.js” 파일을 그대로 복사해도 빌드 없이 동작함
하지만 대형 프로젝트에서는 TS 문법을 선호함
“JSDoc은 TypeScript의 대안이 아니다”라는 주장에 동의함
JSDoc도 정적 분석을 제공하지만 빌드 스텝이 없음
Node 공식 문서 참고
하지만 JSDoc 기반 TS는 브라우저에서도 작동함
나는 개인적으로 TS 문법의 가독성을 선호하며,
swc같은 도구로 타입 제거 속도도 충분히 빠름TypeScript가 다른 대안들을 제치고 승리한 이유는, 새로운 언어가 아니라 타입 체커로 남았기 때문임
초기에 방향이 다소 흔들렸지만, 적절히 수정했고 지금은 대부분의 코드에서 enums조차 잘 쓰지 않음
VSCode에서는 “TypeScript: Prefer Go To Source Definition” 설정을 켜면 실제 소스로 이동 가능함
또한
tsconfig에declarationMap: true를 추가하면 더 정확하게 작동함나는 거의 항상 cmd+click 시 소스 보기를 선호함