타입스크립트 마이그레이션이 완료됐지만 구현할 때 타입명이나 폴더 구조를 신경 쓰지 않고 진행했기에 코드가 엉망진창이었다. 따라서 오늘은 폴더 구조도 변경하고 타입 이름도 조금 더 명시적으로 바꾸어주었다.
폴더 구조
타입스크립트로 프로젝트를 진행하는 건 처음이라 타입을 어떤 식으로 폴더에 정리해야 할지 고민을 많이 했다.
그 과정에서 다른 개발자 분들의 프로젝트도 많이 찾아봤는데, 딱히 어떻게 하면 좋다 그런 건 없는 것 같고 각자 규정한 컨벤션에 따르는 듯하다.
나는 `src > types` 폴더 아래에 각 기능 별로 타입과 인터페이스를 묶어 정리했다.
`index.ts` 파일에서는 정의해 둔 타입 모듈을 모두 export 해 주었다.
// index.ts
export * from "./user";
export * from "./transaction";
export * from "./community";
추후 타입 사용할 일이 있을 때 index 파일에서 타입을 불러와 사용하면 import 코드가 훨씬 간결해진다.
import { PostEntity, UserInfoType } from "../../types";
interface vs type
폴더 구조 관련해서 찾아보다가 우아한 형제들 기술 블로그를 발견했다.
기존에 interface와 type을 공부했을 때, interface는 extends 키워드를 이용해 확장이 가능하고 type은 확장이 불가능하므로
- 타입 객체의 확장성을 위해서 객체 선언 시에는 interface를 사용
- 단순한 원시값(Primitive Type)이나 튜플(Tuple), 유니언(Union) 타입을 선언할 때 type을 사용
이렇게 규칙을 정해서 코드를 작성했었다. 그 결과 내 프로젝트의 타입 선언 대부분은 interface 키워드를 이용해 이루어졌다.
그런데 위의 블로그에서는 현업에서의 개발자들도 사람마다, 기분마다(...!!) type, interface를 혼용해 사용하므로 컨벤션을 정하는 시간을 가졌다는 내용이 나온다. 내가 찾아봤던 내용도 절대적인 건 아니라는 걸 알게 되었다.
블로그 글을 찬찬히 읽어보니 type의 경우 IDE 위에 마우스를 올리면 타입에 대한 상세 정보가 보이지만 interface의 경우 타입이 아예 보이지 않는다고 한다.
직접 확인해 보니 정말 interface로 정의한 타입은 타입 내부 정보가 보이지 않았다.
이 외에도 다양한 이유로 팀에서는 type을 사용하기로 했다고 한다.
나 역시 props 관련 코드는 미리 보기를 위해 interface -> type으로 변경했다.
다만 확장이 필요한 다른 타입들은 interface로 타입 정의를 하기로 했다.
기타 컨벤션 관련해서는 아래 문서도 많은 도움이 되었다.
TypeScript 마이그레이션 완료 소감
마이그레이션을 다짐하기 전까지는 레퍼런스를 검색했을 때 타입스크립트 문법이 보이면 거들떠보지도 않고 뒤로 가기를 눌렀었다;😂 그만큼 타입스크립트는 내게 넘지 못할 벽처럼 느껴졌다.
하지만 이전에 ObjectId 타입과 string 타입의 값을 비교하면서 프로그램이 생각과 다르게 동작했던 경험과 원인을 알아내려 이틀 삼일을 고생한 것을 생각하니 컴파일 시점에서의 에러 체크를 포기할 수가 없었다.
따라서 타입스크립트 마이그레이션을 결정했고, 다행히 자바스크립트 코드에 일일이 타입을 지정하고 오류를 해결하는 과정이 그리 고통스럽지는 않았다.
프로젝트 진행하면서 많은 것을 배우고 느낄 수 있었기 때문에, 지금 와서 돌이켜 봐도 마이그레이션 하길 잘한 것 같다.👍
그럼에도 마이그레이션 과정이 쉽지만은 않았기에 정리해 보자면 이번 마이그레이션 과정에서 특히나 어려웠던 지점은
1. 처음 마이그레이션을 시작했을 때
타입스크립트에 대한 지식이 전무한 상황이라 type과 interface 중 어떤 alias를 써야 할지, 어떤 식으로 이름을 짓고 어떤 범위까지 타입을 지정해야 하는지 알 수 없었다.
2. 리덕스 코드 마이그레이션 부분
리덕스도 아직은 어려운데 그 리덕스의 타입 지정까지 하려니 힘들었다. 다행히 도움이 되는 문서가 있어 따라 했지만 persist 라이브러리의 `persistReducer`함수 타입 관련 오류가 생겨서 해결하는 데 애를 먹었다.
관련한 문서도 국내 것은 아예 없고 해외 문서만 있어서 Flutter 제작할 때 썼던 검색 스킬을 좀 사용했다😏
결국 any를 이용해 문제를 해결했는데 이건 문제 해결도 아니고 그냥 임시방편... 다른 방법이 있는지 계속 찾아보고 다른 방법을 찾으면 다시 포스팅해야겠다.
이번 마이그레이션을 통해 내가 작성했던 코드에 얼마나 많은 타입이 혼재되어 있었는지 뼈저리게 느꼈고, 이게 어디선가 잘못되어 에러로 나타났을지도 모른다고 생각하니 살짝 아찔했다.
자바스크립트는 코드 작성 자체는 자유도가 높지만 프로그램 작동 중에 에러가 발생하고 그 에러가 어디서 발생하는지도 알지 못한다는 게 치명적이긴 하다.
반면 타입스크립트는 코드 작성은 어렵지만(자꾸 IDE에서 에러를 띄우니까...) 그만큼 프로그램 동작 중에는 에러가 발생할 일이 훨씬 줄어들고 에러 발생 지점도 파악하기 쉽기 때문에 에러 수정이 쉽다는 게 아주 큰 장점이라고 생각한다.
이렇게 프로젝트 타입스크립트 마이그레이션은 종료되었지만 아직 부족한 게 많다.
타입스크립트 문법을 공부하고 있는 입장이기 때문에 공부를 더 해나가면서 조금 더 효율적이고 명확하게 코드를 작성하는 법을 배운다면 언제든지 적용해 볼 생각이다.
문법뿐 아니라 폴더 구조도, 나는 일단은 저렇게 구성해보기는 했지만 현업에서는 어떤 식으로 폴더를 구성해 타입을 관리하는지 궁금해졌는데 이건 추후 알아보는 걸로...😂
그리고 이번에 폴더 구조공부하면서 찾아보니 d.ts 파일이라는 것도 존재하던데 d.ts 관련 개념도 따로 공부해서 사용해 보면 좋을 것 같다.
이제 남은 건 추가적인 기능 구현과 코드 중복 제거(리팩토링)다.
꾸준히 프로젝트를 가꿔나가면서 기술적인 능력치를 높이고 싶다.