Typescript에서 ImmutableJS 사용해보기

ImmutableJS 도입하기까지

현재 회사에서 진행하는 프로젝트에 ImmutableJS 의 도입을 결정한 것은 갑작스러운 결정은 아니었다. 물론 React 를 사용하면서 혹은 Redux 를 사용하면서 불변성만 유지된다고 한다면 ImmutableJS 는 필수가 아니라고 생각한다. 사용을 필요한 시점은 데이터의 구조의 깊이가 점점 깊어지면서였다.

/images/react/immutable-with-typescript-image01.png

위에 코드처럼 깊이가 깊지 않은 경우에는 변경하기가 어렵지 않다.

/images/react/immutable-with-typescript-image02.png

그냥 간단하게 전개 연산자를 사용한다면 문제가 되지 않는다. 하지만 만약 그 깊이가 점점 더 깊어진다면 위와 같이 썼을 경우 점점 더 코드가 읽기 힘들어 질 것이다.

/images/react/immutable-with-typescript-image03.png

이와 같은 이유에서 ImmutableJS 를 도입을 결정하였고, 그에 따라 간단한 TodoMVC 를 이용하여 하나씩 예제 코드를 작성해보았다. 이 글에서 사용한 코드는 Github 레파지토리 에서 확인할 수 있다.

ImmutableJS 와 Typescript 함께 사용하기

일단 예제 코드를 작성하기에 앞서 예제 코드는 비지니스 코드에 도입하기 전 사용성 테스트를 하기 위해 최대한 회사에서 사용하는 기술 스택과 동일하게 가져가야 했다. 다른 라이브러리는 동일할 필요는 없지만 제일 중요한 것은 Typescript 에 적용이 되어야 한다는 것이다. 그래서 이 포스팅에서는 ImmutableJS 의 사용을 Typescript 와 함께 사용한 예제에 대해서 설명을 하고 있다.

ImmutableJS 의 사용성을 테스트하기에 앞서 제일 중요하게 생각한 것은 Immutable 객체의 타입에 대한 검증 이었다. 다행이도 ImmutableJS 는 Flow 뿐만 아니라 Typescript 에 대한 호환성에 대해서는 공식 홈페이지에서도 기재되어 있을 정도로 믿을 수 있었다. 먼저 ImmutableJS 를 Typescript로 작성하기 위해서 필자의 경우에는 ImmutableJS 에서 제공해주는 Record 객체를 이용하기로 결정했다. Record 객체를 이용하면 좋은 점은 다음과 같다.

  • 각자의 Record 객체 자체의 기본값을 설정할 수 있으며, 설정되지 않은 값은 추가할 수 없다: Record 객체만 사용하는 경우에 정의 되지 않은 키의 값을 추가하려고 하면 무시된다. 하지만 타입스크립트를 사용하는 경우에는 타입 검증을 통해 바로 알 수 있다.
  • Record 의 기본값을 설정하면서 자체적으로 문서의 기능도 가진다: Record 객체는 앞에서 설명했듯 기본값을 설정할 수 있으며 이는 마치 인터페이스와 같은 역할을 한다. 자바스크립트를 사용하는 경우에는 타입스크립트와는 다르게 인터페이스가 없기 때문에 이는 엄청난 감정이 될 수 있다.
  • Getter 함수를 작성할 수 있다: Record 객체는 팩토리 형태의 함수이지만, Javascript 의 class 형태로 작성되며 이에 따라 원한다면 자체적인 getter 함수를 추가해서 사용할 수 있다.
  • Javascript 의 객체에 접근하듯 Record 객체에도 접근할 수 있다: Record 객체를 이용하면 get() 을 통하지 않더라도 Javascript의 객체와 같이 접근할 수 있다. 다만 IE8 에서는 get() 을 이용해야 한다.

이 포스팅을 읽는 사람들이라면 대부분 TodoMVC 가 구체적으로 어떻게 동작하는지는 다들 알거라고 믿어 의심치 않는다 :-) 혹시나 모르더라도 걱정 안해도 된다. 위의 레파지토리에 모든 코드는 다 올라가져 있으니 코드를 확인하면서 하나씩 읽어나가면 된다.

일단 먼저 Todo 의 아이템을 먼저 Record 객체로 선언을 한다.

/images/react/immutable-with-typescript-image04.png

위와 같이 Record 객체를 Todo 의 인터페이스를 props 로 주입한 후 생성한다. 만약 아래와 같이 정의 되지 않은 프로퍼티를 추가하게 되면 어떻게 될까 ?

/images/react/immutable-with-typescript-image05.png

그렇게 되면 아래의 그림과 같이 타입스크립트 빌드 과정에서 에러를 내뱉어준다.

/images/react/immutable-with-typescript-image06.png

마찬가지로 제일 중요하게 생각한 타입 검증도 역시 테스트를 해보았다.

/images/react/immutable-with-typescript-image07.png

임의의 타입을 변경해도 이전의 테스트와 마찬가지로 검증을 해준다.

/images/react/immutable-with-typescript-image08.png

이렇게 검증된 state 는 이제 reducer 에서 쉽고 편하게 사용할 수 있다. 아래의 사진은 reducer 의 전체 코드이다.

/images/react/immutable-with-typescript-image09.png

이쯤되면 마지막으로 궁금한 것이 생길 것이다. 과연 타입이 일치하지 않는 값을 대입할 때 역시 타입 검증을 제대로 해줄 것인가?

/images/react/immutable-with-typescript-image10.png

역시나 reducer 에서 state 의 값과 일치하지 않을 때 역시 탄탄하게 검증을 해준다.

/images/react/immutable-with-typescript-image11.png

추가로 말하자면 Record 를 선언하는 방식은 위와 같은 방식 말고도 class 형태로 선언하는 방식도 있다. 위에서 장점으로 말했던 4가지 중 3번째 항목 중 자체적인 getter 함수를 작성할 수 있다 에 해당하는 방식인데, 그러한 경우는 아래와 같이 선언을 하면 된다.

/images/react/immutable-with-typescript-image12.png

이상으로 ImmutableJS 의 Record 객체에 타입스크립트를 적용하는 것을 살펴보았다. 물론 아직은 조금 더 사용성에 대해서 살펴본 후, 실 서비스에 적용을 하겠지만 지금까지 살펴본 바로는 큰 학습 비용 없이 적용이 가능하다는 것이 큰 장점인 것 같다.


출처

현재 이커머스회사에서 frontend 개발자로 업무를 진행하고 있는 Martin 입니다. 글을 읽으시고 궁금한 점은 댓글 혹은 메일(hoons0131@gmail.com)로 연락해주시면 빠른 회신 드리도록 하겠습니다. 이 외에도 네트워킹에 대해서는 언제나 환영입니다.:Martin(https://github.com/martinYounghoonKim
2018년의 회고
SPA 환경에서의 인피니티 스크롤