저는 TypeScript 개발자가 절대 아니었습니다. 그리고 여전히 JavaScript에 대해서 TypeScript는 필수로 적용해야 할 기술이라고 생각조차하지 않습니다. 개인적으로 TypeScript를 적용한 이후에 몇 개월이 지났습니다. 그리고 지금 TypeScript와 함께 하는 개발은 실제로 어떻게 저에게 다가왔는지 그리고 어떻게 쓰면 좋을지 정리하려고 합니다.


TypeScript로 넘어가는 과정들

제가 처음 TypeScript를 사용할 때에는 저의 마음에는 딱 그것 뿐이었습니다. 외주에서 요구하는 스택의 일종이었기 때문입니다. 그동안 인수인계를 받은 프로젝트도 있고 제가 끝낸 프로젝트도 굉장히 많았습니다. 하지만 그 당시까지만 해도 솔직히 '왜' 써야 하는가는 크게 느껴지지 않았습니다. 되려 상당히 평범하다고 생각했던 JavaScript에서의 트릭들이 Lint에 걸려 넘어지는 것을 보고서 비용이 오히려 더 많이 드는 것이 아닌가 하는 생각도 들었습니다.

실제로 그 때에도 저는 JavaScript만으로도 머릿속에서 타입에 대한 추론이 되고 있었습니다. 그리고 적용하지 않았습니다. 굳이 필요한가?라는 생각이 들었기 때문입니다. 지금도 일부 프로젝트에는 그렇게 생각합니다.

그리고 다시 그 이후로 몇 개월이 지났고 이제는 제 공개 라이브러리에 TypeScript를 적용할 때가 왔습니다. 그리고 그 때 처음 알았습니다. 읽을 수는 있지만 제대로 쓰기에는 턱없이 부족할 수 있다는 것을 말이죠. 상당히 늦은 감이 있었음에도 불구하고 일단 새 TypeScript 프로젝트도 만들어보고 이게 어떤 역할을 해야 하고 하나의 레이어가 추가된 상황에서 코딩은 어떻게 해야 하는지 등등... 여러가지를 보고 배우기 시작했습니다. 이렇게 제 TypeScript 생활이 시작되었습니다.

TypeScript 생활은 쉽지 않았습니다. 차라리 JavaScript를 하고 JSDoc을 먼저 사용하는 것이 훨씬 좋습니다. TypeScript를 먼저 배우는 것이 편하다는 입장도 분명히 이해가 갑니다. 하지만 기존에 JavaScript만을 하고 있던 사람에게는 JSDoc을 먼저 보여주고 자신이 적어왔던 코드에 대해 기준을 정하는 일이야 말로 TypeScript가 개발 비용을 어떻게 줄여주는지 더욱 잘 인식시켜준다고 생각합니다. TypeScript는 한 마디로 사람들이 말하는 것처럼 '처음', '첫 번째로'? 아닙니다. 절대 쉽지 않습니다.

TypeScript over ESlint? JSDoc over TypeScript: 점진적인 도입과 그 과정 속에서의 학습

TypeScript는 쉽지 않고 절대 필수적이지 않습니다. 어렵다면 JSDoc을 먼저 해보세요.

시작하기 전 저의 가장 큰 궁금점은 바로 그것이었습니다. ESLint로도 사실 코딩을 하는데에 충분하지 않은가? 하는 것이었습니다. 왜냐하면 기본적으로 저희가 TypeScript를 사용하는 이유는 Typing을 하여 자신의 코드를 더욱 더 믿음직하게 바꾸는 것이라고 생각했기 때문입니다. 지금 이 생각이 틀렸다고 생각하지는 않습니다. 왜냐하면 지금와서 봐도 저는 여전히 충분히 맞는 말이라고 생각하기 때문입니다. TypeScript에서 제가 얻는 이득은 실행 시의 비용보다는 개발 시의 비용에서 나오기도 합니다.

하지만 프로젝트가 더욱 거대해지면서 사람들의 니즈는 왜 TypeScript를 향하는가를 느끼는 시점이 생겼습니다. 거대한 프로젝트 안에서 ESLint는 무의식적으로 생긴 오타를 잡기에는 턱없이 부족했습니다. 외주에서는 시간이 여유로운 경우는 찾아보기가 굉장히 힘듭니다. 그래서 제 손은 더욱 더 많은 오류를 일으켰고 이를 잡는데에 낭비한 시간들은 굉장히 아까웠습니다. 여전히 TypeScript를 사용하여 TypeScript까지 신경 쓸 시간이 충분한 프로젝트는 많지 않습니다.

그러다 문뜩 한 번 TypeScript가 생각났습니다. 'TypeScript에서는 이러한 스펙을 자동으로 분석해주었지'하는 생각이 들었습니다. 당시에 약간이나마 TypeScript를 시도해보았기 때문입니다. 그리고 이 순간에 제 머릿속의 타입 추론 기능은 박살이 난 것 같았습니다. 그래서 바로 당장 TypeScript 웹 사이트에 들어갔습니다. 단순히 적용을 위해서 그리고 간편하게 사용할 수 있는 방법은 없는지 찾아보기 위해서였습니다. 그리고 JSDoc을 발견했습니다.

처음 발견했을 당시에는 저는 이것으로 다행이라는 생각이 들었습니다. 제가 쓴 변수들에 대해서 미리 스펙을 정해놓을 수 있었고 이것은 충분히 많은 오타를 방지해주었습니다. 물론 이는 TypeScript 덕분이기도 합니다. Microsoft가 만든 Visual Studio Code의 JavaScript 기능들에는 분명히 TypeScript가 발전하면서 동시에 발전한 기능이 있을 것이기 때문입니다. 그리고 새로 생긴 기능들 덕에  JSDoc은 기존 이상의 성과를 낼 수 있었다고 생각합니다.

JSDoc을 사용하면서 당시 제 코드들은 더욱 더 리치해지기 시작했습니다. 이전에 개발할 때에는 머릿속에 모든 정보들을 들고 다녔습니다. 그래서 그 때에도 굉장히 다양한 저만의 전략들을 만들고 다녔습니다. 예를 들어서 이전에는 서비스 로직을 분리할 때 로직마다 공통적인 변수 혹은 함수명을 채택했습니다. 이 또한 제가 헷갈리지 않기 위한 하나의 방식입니다. 하지만 JSDoc을 사용하면서 전역적까지는 아니더라도 지역적으로 제가 정형화된 코드를 코딩할 수 있도록 변화했습니다.

그리고 그 때의 헷갈렸던 경험을 이후로 제 코드는 훨씬 리치해졌는데 아래는 사용자를 생성하는 하나의 함수입니다. 그리고 지금 TypeScript는 이에 대해서 전역적으로 JSDoc이 하던 기능을 제공하고 있습니다.

/**
 * Create user and push it to database
 *
 * @param user The valid user object containing all properties, the identifier is optional
 */
export const create = async (user: IUserProps): Promise<void> => {
  const trx = await client.transaction()

  await trx('users')
    .insert({
      ...user,
      id: snowflake.getUniqueID() as string
    })
    .catch(trx.rollback)
    .then(trx.commit)
}

다시 와서 생각해봤을 때 저는 더 많은 개발자 그리고 애플리케이션 아키텍트분들이 TypeScript를 점진적으로 도입하셨으면 좋겠습니다. 단순히 물론 처음부터 누군가에게 이건 당연한 것이고 이렇게 해야 한다고 알려주어도 적성에 따라서 더 잘 배우는 사람이 있을 것입니다. 하지만 제가 스스로 TypeScript를 필요하다고 느꼈던 시점은 프로젝트 크기가 커져 많은 변수들에 대해 모든 것을 세세하게 알기가 힘들었을 때입니다. 이것이 의미하는 것이 저는 단순히 TypeScript가 Typing을 해주어서 나타난 효과라고는 볼 수 없다고 생각합니다.

TypeScript는 Typing을 추가한 것이 아니라 각각 개별 변수에 대해서 사이드이펙트를 설명할 수 있다는 것이 제가 TypeScript를 쓰면서 가장 크게 느낀 점입니다. 다시 주석을 적어나가면서 함수가 해야 할 일을 하나로 만들어주고 복잡성을 줄이는 것이 제일 도움이 많이 되었습니다. 단순히 적용하는 것으로는 이러한 학습으로는 도달하기가 힘들다고 봅니다. 단순히 적었을 때나 TypeScript를 사용해 단순히 적었을 때 모두 저는 규모가 커지면 코드가 내제하는 것을 쉽게 알 수 없다는 점에서 그리고 주석을 추가하지 않아 다시 생각할 시간을 주지 않는다는 점에서 기본적으로 Typing이 주는 효용은 적다고 봅니다.

저는 화려한 문법을 좋아하지 않습니다. 읽기 편하고 쉽고 단순한 코드를 더 선호합니다. 그리고 TypeScript는 만병통치약이 아닙니다. 저는 TypeScript 덕분에 문서화가 필요없어졌다는 말을 믿지 않습니다. 아무리 이과라고 한들 설명은 들어야죠.

JavaScript over TypeScript: TypeScript를 적용해야 할 때 그리고 하지 말아야 할 때

개인적으로 굉장히 다른 의견의 여지가 많은 글입니다. 다들 아시다시피 개인적인 생각입니다. 지적해도 괜찮습니다. 하지만 모든 사례는 그에 대한 배경에서 나오는 이유가 있다 생각하기 때문에 틀린 말 없다 생각합니다.

제가 TypeScript를 적용하지 말아야 한다고 했을 때 최우선으로 생각하는 것은 지금 시점에서 거의 정해져 있습니다. 개발에 드는 비용을 생각했을 때 TypeScript를 컴파일하는 과정을 배포까지 전역적으로 추가하는 것이 큰 지 혹은 단순히 JSDoc과 같이 한 파일에 대해서 지역적으로 코드를 설명할 수 있도록 만드는 것이 더 큰 지가 주된 관건입니다.

누군가는 명령어 한 줄이라고 할 수도 있지만 컴파일하는 과정이 추가된다는 것은 단순히 build 명령어 넣고 tsconfig.json 넣고 하면 끝나는 문제가 아닙니다. 물론 정말로 지금은 귀찮은 과정을 단순화해주는 서비스도 많고 CI-CD 통합 솔루션도 많습니다. 그리고 심지어는 애플리케이션 레벨에서 전부 다 관리해주고 처리해주는 솔루션도 있습니다. 하지만 제가 언급하고 싶은 사항은 단순히 이 한 프로젝트를 개발할 때 집어넣는 것이 아니라 개발부터 배포, 그리고 오류 추적까지 이 모든 과정에서 TypeScript를 도입했을 때 단순히 개발 시의 이득을 얻을 수 있을 정도가 아니라 모든 과정에서 제대로 이전처럼 활용이 가능한지 입니다. 예를 들어서 TypeScript를 정말로 쉽게 사용하게 해주는 패키지인 ts-node가 없다고 쳤을 때 컴파일된 코드가 실행된 결과만을 가지고 여러분의 팀이나 조직이 오류에 대한 정보를 그 때 그 때 충분히 얻는 것이 가능한지 생각해보세요.

이러한 점을 살펴보았을 때 절대로 쉽게 도입해서는 안 되는 사안이라고 생각합니다. 대신에 주석을 최소한 함수 하나에 한 줄만 추가한다고 생각을 해보세요. 주석을 적으면서 이 함수가 단순히 한 가지 일을 하는 것이 맞는지 생각할 틈을 주는 것이 여러분의 프로젝트 내 코드들을 더 잘 카테고라이징할 수 있도록 도와줄 것이고 내재적인 문제점을 찾는지 도와줄 수 있다고 생각합니다.


JavaScript 생태계에 있는 사람으로써 분명히 언젠가는 딥하게 시도해야 하는 분야가 맞다고는 생각합니다. 하지만 그에 앞서서 지금 하는 것이 정말로 어느 효과를 가져올 지는 두 번 세 번 생각해도 늦지 않다고 생각합니다.