타입스크립트, 써야할까?

TypeScript 설문조사 스크린샷

최근 페이스북의 프론트엔드 개발그룹에 설문이 있었다. 타입스크립트를 도입하지 않는 이유에 대해서 묻는 설문이었는데, 한 사람의 타입스크립트 유저로서 보고있기가 정말 괴로운 설문이었다. 그 글을 보고 예전부터 쓰다가 말고를 여러 번 반복한 주제를 꺼냈다. 주제는 바로 타입스크립트를 써야할, 혹은 쓰지 말아야 할 이유. 사실 이 글은 타입스크립트를 써야할 이유에 더 가까울 것이다. 타입스크립트를 좋아하시는 분들이 많이 계시지만 거부감을 가지고 계신 분들도 많이 보았기에 한 번 쯤은 글로서 설득해보고 싶었다.

본론을 시작하기에 앞서, 이 글은 일개 타입스크립트 유저가 작성한 매우 주관적인 의견이라는 점을 확실히 해두고 싶다. 기술에 절대적인 선이나 악은 존재하지 않으며, 마찬가지로 기술적인 선택에 있어 정답이나 왕도는 없다. 이 글의 논조 자체가 타입스크립트 우호적으로 작성되었기 때문에 이 글을 보는 독자 입장에서는 마치 타입스크립트를 사용하는게 답이라는 듯 말하는 것처럼 느껴질 수 있지만, 실제로는 절대 그렇게 생각하지 않는다고 밝혀두고 싶다. 개인의 선택을 존중한다.

본문에서는 크게 다섯 가지로 나눠 러닝커브와 도입, 생산성, 안정성, 함수형 프로그래밍, 커뮤니티 측면에서 타입스크립트를 살펴볼 것이다. 이 글에서는 타입스크립트만 콕 집어 다루고 있지만, Flow등의 다른 정적 타입 도구도 상황은 크게 다르지 않을 것이라 예상된다.

📝 러닝커브, 도입

사실 나는 아직도 타입스크립트를 주저하는 이유로 러닝커브를 꼽는 사람이 있다는 것에 놀랐다. 물론 타입스크립트가 쉽냐는 질문에는 쉽지 않다고 대답할 것 같다. 그렇지만 자바스크립트에 비해서 러닝 커브가 심하게 가파르다고 할 수도 없다. 더구나 ES2015, 그 이후의 문법에 익숙한 사용자라면 큰 어려움 없이 시작할 수 있다. 그 이유는 자바스크립트의 수퍼셋이라는 타입스크립트의 특성 때문이다.

타입스크립트의 가장 기본적인 기능은 단순히 자바스크립트에 타입 표기법을 추가하는 것이기 때문에, 만약 string이나 number등의 자료형을 잘 모르는 사람이 아니라면, 타입스크립트를 단순히 도입하는 것은 별로 어렵지 않다. 더구나 기존 자바스크립트 기반의 프로젝트에서도 일부 파일만 타입스크립트로 바꿔서 부분적으로 사용하는 것도 가능하기 때문에 점진적 도입도 할 수 있다.

“잘 쓰고싶다”는 얘기가 조금 다르다. 자바스크립트와 마찬가지로 타입스크립트에는 수 많은 기능들이 있고, 개 중에는 배우기 어렵고 난해한 기능들도 있다. 특히 그 전 정적 타입 언어를 사용했던 유저라면 금방 이해할 수 있겠지만 그렇지 않은 사람에게는 배우기 어려운 개념들도 있다. 이런 기능들은 처음부터 당장 잘 사용해야되는 것들은 아니다. 분명히 자바스크립트를 사용했을 때보다는 알아야 할 게 늘어난다. 하지만 그 어느 누구가 그 모든 기능들을 다 사용하고 있을까? 프로그래밍 언어라는 특성상 사용자의 역량에 따라 응용도가 크게 차이나고, 그 한계가 명확히 존재하지 않는다. 시간이 지남에 따라 커뮤니티가 성숙하고 언어를 사용하는 법 역시 성숙한다. 타입스크립트는 심지어 다른 언어에 비해 릴리즈도 자주 일어나기 때문에 더욱더 마스터에 근접하기는 어려운 언어다. 그런 상황에서 이 언어의 모든 걸 알아야 한다고 생각한다면 타입스크립트는 어려운 언어가 될 수 밖에 없다. 이 글을 쓰는 나도 잘 쓰고 있다고 말하기는 어렵다. 지속적인 개선이 있을 뿐이다.

결론적으로 배우기 어려워서, 도입 비용이 커서 타입스크립트를 선택하지 않는다는 것은 섣부른 걱정이라는 생각이다. 프로그래밍 언어를 처음 배웠을 때로 되돌아가보자. printf("Hello, world!"); 컴파일러, 타입은 물론이고 세미콜론이 뭘 의미하는지도 모르는 시절에도 일단 코드부터 쳤다. 처음부터 다 하려고 하면 당연히 포기가 더 가깝다. 차근차근히 일단은 내가 할 수 있는 작은 것부터 시작하면 되는 거고, 타입스크립트는 점진적으로 나아가기에 좋은 언어다.

더 읽기: Why You Shouldn’t Be Scared of TypeScript

🔥 생산성

정적 타이핑과 동적 타이핑의 생산성에 관한 논쟁은 상당히 오래된 떡밥이고 이 역시도 아직 모든 상황에서 “타이핑을 하는 것이 우위다.” 혹은 “타이핑을 안하는 것이 우위다.”라고 절대적인 결론이 나지는 않았다. 단순히 더 많은 코드를 작성해야하니 생산성이 떨어지게 된다는 주장은 너무 일차원적인 의견이다. 상황에 따라, 사용자에 따라, 보다 적절한 선택이 있을 것이다. 이 주제에 대한 일반적인 의견은, 동적 타이핑은 단기적으로 사용할 경우에 뛰어난 생산성을 보여주지만, 다수의 사람들이 장기적으로 유지보수 할 때에는 어려움을 느낄 가능성이 높다는 것이다. 물론 정적 타이핑은 이 반대의 우위를 가지고 있다. 자바스크립트와 타입스크립트의 관계도 마찬가지다. 타입스크립트는 장기적으로 생산성에 나은 선택이 될 가능성이 높다.

최근 자바스크립트가 활용되는 영역에 한계가 거의 없다시피 하지만 여전히 가장 많이 사용되는 곳은 프론트엔드 프로젝트다. 과거 웹이 Multi Page Application(MPA) 기반으로 작성되었던 것과는 달리 요즘 웹페이지는 대부분 React와 Vue, Angular등을 사용한 Single Page Application(SPA)으로 작성된다. 두 가지 타입의 웹에서는 프론트엔드에 기대하는 바도 다르다. 과거 MPA의 프론트엔드에서는 (사실 예전에는 프론트엔드라고 부르는 영역자체가 없었다) HTML 렌더링을 백엔드에서 했기 때문에, 단순한 AJAX 처리 후 DOM 조작을 이용한 극히 부분적 렌더링 정도만을 JavaScript로 처리했었다. 반면, 요즘 SPA에서는 대부분의 HTML 렌더링을 프론트엔드에서 처리한다. 그 결과, 프론트엔드가 백엔드의 역할을 상당히 많이 흡수하게 되었다. HTML 렌더링, 페이지 라우팅, 일부 비즈니스 로직, 어플리케이션 상태 저장 등등. 더구나 예전에는 프론트엔드가 굳이 알 필요 없었던 DB 모델링 스키마도 이제는 프론트엔드에서 당연히 알아야 하는 부분이 되어버렸다. 따라서 요즘 SPA 프론트엔드 프로젝트는 과거 MPA 프로젝트보다 규모가 훨씬 커졌고, 더 많은 사람들이 더 오랜기간 만들고 유지보수해야할 가능성이 높아졌다. 최근 타입스크립트의 가파른 성장도, SPA 프로젝트가 점점 많아지고 있는 현 트렌드와 무관하지 않다는 것이 내 생각이다.

생산성 부분에 있어서 내 결론적인 의견은, 프로젝트 규모에 따라 타입스크립트는 도움이 될 수도, 안 될 수도 있다는 것이다. 프론트엔드에서는 SPA의 코드 규모가 MPA보다 크기 때문에 정적 타이핑에 유리하며, 프로젝트가 더 대규모일수록, 그리고 더 장기간 유지보수할 가능성이 높아질 수록 타입스크립트의 장점이 부각된다.

더 읽기: What is the supposed productivity gain of dynamic typing? (Stack Exchange)

✅ 안정성

정적 타이핑과 안정성 얘기하면 항상 링크가 걸리는 글이 있다. The broken promise of static typing이라는 상당히 자극적인 제목을 가지고 있는 이 글에서는 정적/동적 타이핑 여부와 버그의 발생 빈도 사이에는 큰 관계가 없다는 결론을 상당히 설득력있는 근거와 함께 설명하고 있다.

타입스크립트 유저로서 이 글의 결론이 썩 마음에 들지는 않지만, 근거가 분명하기 때문에 충분히 동의할 수 있다. 타입은 런타임에서의 에러 발생 확률을 줄여주지만, 그것이 반드시 버그 감소로 귀결되지는 않는다. 마찬가지로 어플리케이션의 안정성으로 이어지지도 않는다. 물론 여전히 안정성을 이유로 들어 타입스크립트를 선택하는 사람이 있지만, 나는 생각이 다르다. 정말로 버그를 줄이고 싶다면 타이핑에 만족하지 말고, 테스트를 더 잘 짜는데 주력해야한다. 게다가 타입스크립트를 쓴다고해서 테스트를 안짜도 되는 것도 아니다.

그럼 타입스크립트를 쓸 이유가 없지 않느냐고 반문 할 수도 있는데, 정적 타이핑의 진짜 강점은 런타임 에러 감소에서 오는 것보다는 빠른 에러 발견과 해결에 있다. 같은 타입 에러라고 하더라도 런타임에 발견하는 것과 컴파일 타임에 발견하는 것은 개발자가 보고 판단하고 수정하는 데 걸리는 시간이 다르다. 컨텍스트 스위칭 비용도 없다. 리팩토링할 때 이 장점은 더욱 빛나는데, 리팩토링 이후 Find & Replace 해놓고 런타임에서 에러를 일일히 확인하지 않으면 안심할 수 없는, 결국 리팩토링의 영향이 닿는 모든 기능을 확인하기 전에는 확신하기 어려운 자바스크립트와는 달리, (타이핑을 잘했다는 가정하에) 타입스크립트는 컴파일 타임에 어느 부분이 깨지는지 빠짐없이 알려주기 때문에 리팩토링하기 편해지고, 리팩토링에 대해서 열린 마음을 갖게 된다. 결론적으로 타입 에러를 컴파일 타임에 발견해서 얻는 이득은 런타임에서의 안정성보다는 더 좋은 개발경험과 생산성, 그리고 그로 인해 얻게 될 더 좋은 코드에 가깝다.

더 읽기: The Shocking Secret About Static Types

🤔 함수형 프로그래밍

현재까지 이 부분은 확실한 결론이 나지 않은 주제라는 생각이 든다. 확실히 함수형 프로그래밍을 할 때 주로 사용되는 lodash나 Ramda등의 라이브러리에서 제공하는 커링, 컴포지션 그리고 맵, 필터 등의 함수를 타입스크립트로 사용할 때, 들어가는 파라미터와 리턴 타입이 자동으로 타입 추론이 되지 않기 때문에 일일이 제네릭으로 타입을 넘겨줘야하는 불상사가 일어난다. 그리고 이건 확실히 번거롭다. 결론적으로 타입스크립트는 딱히 자바스크립트에 비해 함수형 프로그래밍하기가 더 좋은 언어는 아니다. 그렇지만 함수형 프로그래밍을 하기에 좋지 않은 언어인가에 대해서는 아직 토론할 여지가 남아있다. 어쨌든 타입스크립트는 자바스크립트의 확장이기 때문에 자바스크립트로 할 수 있는 것을 할 수 없는 것은 아니다. 문제가 되는 함수형 프로그래밍 부분의 번거로움을 감수한다면 함수형 프로그래밍의 장점과 타입스크립트의 장점을 동시에 가져갈 수 있으며, 그런 번거로움을 감수하기 싫다면 타입스크립트의 장점을 해당 부분에서만 버리면 된다. 그리고 타입스크립트는 그걸 허용할만큼 관대한 언어다.

만약 타입스크립트에서의 함수형 프로그래밍이 아쉽게 느껴질정도로 함수형 아이디어를 자주, 많이 사용하고 있다면, 다른 언어를 찾아보는 것도 합리적인 대안이 될 수 있다. 자바스크립트를 지원하는 함수형 프로그래밍 언어는 Elm, Reason, ClojureScript 등이 있다.

더 읽기: Functional Programming with TypeScript

🌱 커뮤니티

타입스크립트의 사용자는 해마다 가파르게 상승하고 있다. 스택오버플로우에서 해마다 실시하는 Developer Survey 2018년 결과를 보면 타입스크립트는 Most Popular Technologies 12위에 랭크되어있다. GitHub Octoverse 2017에서는 11위에 올랐다. 그만큼 사용자가 많고 그만큼 커뮤니티가 크다. 커뮤니티가 크다는 것은 당연하지만, 내가 참고할 자료가 많다는 것, 디테일한 부분에서 언어 자체에 대한 지원이 잘되어있다는 걸 의미한다. 후술하겠지만 이런 타입스크립트의 커뮤니티가 크다는 것을 반증하는 가장 좋은 예가 바로 DefinitelyTyped)라는 레포지토리다. 여기에는 우리가 알고 있는 웬만한 메이저 라이브러리, 프레임워크의 타이핑이 거의 모두 정의되어 있다. 또한 2017년에 가장 많은 리뷰를 받은 GitHub 레포지토리이기도 하다.

d.ts

d.ts는 단점이다. d.ts 그 자체가 단점이라기 보다는, d.ts 파일의 존재 여부에 따라 라이브러리 선택이 갈리는 것, 의존성에 @types/*** 패키지를 추가해야하고 그 역시 유지관리가 필요하다는 것. 자바스크립트와 npm을 사용하는 강점을 상당히 까먹는 부분이다. 처음 타입스크립트를 시작한 사람에게는 큰 진입장벽이다. 일단 d.ts 파일은 일반 타입스크립트 파일에서 보기 힘든 문법을 가지고 있어서 몇 번 정의해본 사람이 아니면 쉽게 정의하기도 어렵다. DefinitelyTyped에 많은 라이브러리의 타이핑이 정의되어 있긴 하지만, 마이너한 라이브러리의 d.ts 파일은 종종 정의되어있지 않은 경우가 있어서 사용을 포기한 적도 있고 직접 만들어 사용한 적도 꽤 많은 만큼, 타입스크립트 유저라면 대부분이 맞닥뜨리는 상황이다.

d.ts도 제공을 안하고 DefinitelyTyped에도 없는 패키지라면 선택은 두 가지다. 타입스크립트를 지원하는 다른 라이브러리를 찾아보거나, 직접 d.ts 파일을 만드는 것이다. 나는 반드시 사용하고 싶은 라이브러리가 있는 경우 무조건 d.ts 파일을 만들어두고 쓰는데, 처음엔 사용하는 API 몇 개 정도만 타이핑을 해두다가 차차 타이핑을 늘려나가는 방식을 선호한다. 그리고 어느정도 타이핑이 안정적이라는 생각이 들면 해당 라이브러리 레포지토리나 DefinitelyTyped에 PR을 날려볼 수도 있다. 이 문제를 정말 신경쓰기가 싫다면 noImplicitAny 옵션을 켜두면 된다.

때로는 이 때문에 리서치에 시간을 잡아먹기도 하는 만큼 가벼운 단점은 아니라고 생각한다. 하지만 타입스크립트 커뮤니티가 커지는 만큼 맞닥뜨릴만한 상황은 앞으로 점점 적어질 것이라고 예상한다.

👌 결론

나는 사실 지금까지 순수 자바스크립트를 사용해서 코딩한 경험이 많지 않다. 지금 다니는 회사에 들어오기 전까지는 쭉 커피스크립트만 썼었고(그걸 까는 글도 썼었고), 지금 회사에 들어온 이후로는 쭈욱 타입스크립트만 써왔다. 따라서 정당한 비교는 되지 않을지 모르겠지만, ES2015이후의 자바스크립트와 타입스크립트 중에 뭐가 더 개발자의 경험적인 측면에서 나은 언어였냐고 물어본다면 무조건 타입스크립트를 꼽을 것이다. 프로그래밍 언어가 제공하는 가치 중에서 개발자의 경험보다 중요한 것이 있을까? 그 면에서 타입스크립트는 개발자의 경험을 거의 만족에 가깝게 끌어올려주는 언어고, 좋은 언어라고 자신있게 말할 수 있다. 타입스크립트의 깃허브 레포지토리에는 Love for TypeScript라는 이슈가 있을 정도로 사용자의 만족도가 높은 언어다. 물론 당장 사용하지 않으면 큰일날 것도 아니고, 현재 자바스크립트로 충분히 만족하고 있다면 굳이 사용할 필요가 없는 것도 사실이다. 하지만 새로운 프로젝트에 한 번 쯤 시도해봐도 나쁘지 않을 정도로 가치있는 언어이기도 하다. 만약 타입스크립트에 대한 선입견이 있었다면, 이 글을 통해 선입견이 조금이라도 줄었기를 바란다.

👀 더 읽어볼 만한 글

아래 목록은 읽기를 추천하는 타입스크립트에 관한 글들이다. 이 글을 쓰면서 참고한 부분이 많기 때문에 이 글을 재밌게 보았다면 아래 글들도 반드시 보기를 추천한다.