Any 타입을 걷어내고 깨달은 것들: 인디 해커를 위한 실전 TypeScript 타입 설계와 AI 코딩의 이면

Author Kini
·

1인 개발자로서 SaaS를 빌딩하다 보면 가장 큰 적은 ‘미래의 나’입니다. 당장 기능을 돌아가게 하려고 대충 짜놓은 코드는 정확히 3개월 뒤, 혹은 기능을 추가하려는 바로 그 순간에 부메랑이 되어 돌아오죠. 최근 에디터 관련 기능을 전면 수정하며 제가 가장 많이 마주한 문제는 바로 무분별한 any 타입의 사용이었습니다.

이번 글에서는 제가 겪은 기술적 삽질과 이를 해결한 구체적인 방법, 그리고 요즘 누구나 한다는 ‘바이브 코딩’에 대한 제 솔직한 견해를 정리했습니다. 워드프레스 독자분들은 개발 지식이 있으신 분들이 많으니, 바로 코드로 들어가 보죠.

DB 스키마와 프론트엔드 타입의 간극

우리는 보통 데이터베이스에서 생성한 스키마를 기준으로 프론트엔드 타입을 정의합니다. 하지만 실제 구현에 들어가면 문제가 생기죠. DB에서는 필수로 요구하는 값이 프론트엔드 생성 단계(Draft)에서는 필요 없거나, 수정 시에는 일부만 사용하고 싶을 때가 많거든요.

이때 많은 개발자가 귀찮다는 이유로 any를 쓰거나, 거의 똑같은 타입을 수동으로 다시 정의합니다. 저도 처음엔 그랬어요. 하지만 이건 유지보수 관점에서 재앙에 가깝습니다.

해결책: Utility Types의 영리한 조합

타입스크립트의 Partial은 획기적이지만 조금 부족합니다. 모든 필드를 옵셔널로 만들어버리니까요. 제가 이번에 적용한 방식은 OmitPartial을 적절히 섞는 것이었습니다.

TypeScript

// DB에서 가져온 기본 스키마 정의
export type Project = project;

// 복잡한 에디터 설정(config) 필드는 별도의 타입으로 관리하고 싶을 때
export type ProjectOptional = Omit<Partial<Project>, 'config'> & { 
  config?: PageContent;
};

이 방식의 흐름은 이렇습니다.

  • Partial<Project>: 프로젝트의 모든 필드를 일단 선택 사항으로 바꿉니다.
  • Omit<..., 'config'>: 그중에서 특별한 처리가 필요한 ‘config’ 필드만 도려냅니다.
  • & { config?: PageContent }: 도려낸 자리에 제가 원하는 타입(PageContent)을 다시 주입합니다.

이렇게 하면 DB 스키마와의 연결성은 유지하면서도, 프론트엔드 상황에 맞는 유연한 타입 정의가 가능해집니다. 에디터 항목들에서 발생하던 정체불명의 이슈들이 이 타입 정의 하나로 90% 이상 해결되었습니다.

💡 Tip: any를 지우는 시간은 절대 낭비가 아닙니다. 런타임 에러를 잡느라 쏟을 수천 분의 시간을 지금 10분의 타입 설계로 아끼는 겁니다.

‘바이브 코딩’이라는 달콤한 함정

요즘 AI의 도움을 받아 코드를 짜는 ‘바이브 코딩(Vibe Coding)’이 대세입니다. 저도 인디 해커로서 속도가 생명이라 AI를 적극적으로 활용합니다. 하지만 이번 리팩토링을 통해 뼈저리게 느낀 점이 있어요. AI도 결국 ‘남’이라는 사실입니다.

투박하게 프롬프트를 던져서 얻어낸 코드는 당장 잘 돌아가는 것처럼 보입니다. 하지만 그 코드의 이면을 100% 이해하지 못한 채 ‘복붙’에 의존하면, 유지보수 단계에서 속도가 어마어마하게 차이가 납니다.

내가 이해한 코드 vs 남이 짜준 코드

  • 유지보수 속도: 내가 설계한 코드는 문제가 생겼을 때 어디를 건드려야 할지 본능적으로 압니다. 반면 바이브 코딩으로 만든 코드는 오류를 수정할 때 다시 AI에게 물어봐야 합니다. 주객이 전도되는 거죠.
  • 안정성의 한계: AI는 단편적인 코드 조각을 주는 데 탁월하지만, 내 서비스 전체의 맥락이나 타입 시스템의 안정성까지 깊게 고민해주지 않습니다.
  • 숙련도의 격차: 바이브 코딩의 결과물을 그대로 쓰는 사람과, 이를 분석해서 나만의 스타일로 변환(Convert)하는 사람의 실력 차이는 시간이 갈수록 기하급수적으로 벌어집니다.

시제품(MVP) 출시 단계에서 바이브 코딩은 강력한 무기입니다. 하지만 그 코드를 내 것으로 변환하는 숙련도를 올리지 않는다면, 그 무기는 결국 나를 향하게 됩니다. 유지보수 단계에서 발생하는 ‘기술 부채’는 그 어떤 고금리 사채보다 무섭거든요.

💡 Tip: AI가 짠 코드를 이해하지 못했다면, 그 코드는 아직 당신의 것이 아닙니다. 반드시 한 줄씩 뜯어보며 왜 이렇게 짰는지 스스로 답을 내놓아야 합니다.

기술적 회고와 1인 개발자의 자세

5년 차 개발자로 일하며 깨달은 건, 코드를 잘 짜는 것보다 ‘읽기 좋은 코드를 유지하는 것’이 훨씬 어렵다는 점입니다. 특히 혼자서 모든 것을 결정해야 하는 인디 해커에게는 자기 검열이 필수적입니다.

any를 제거하기 위한 시간은 항상 모자랍니다. 기능 개발만 하기에도 벅차니까요. 하지만 그 모자란 시간을 쪼개서 타입을 정교화하고, AI의 코드를 내 것으로 만드는 과정이 있어야만 서비스가 장기적으로 생존할 수 있습니다.

이번 에디터 리팩토링 과정은 단순히 버그를 잡는 시간이 아니었습니다. 제가 만들고 있는 SaaS인 ‘PMF Verify’의 근간을 다시 다지는 시간이었죠. 여러분의 프로젝트는 어떤가요? 혹시 any 뒤에 숨어있는 시한폭탄을 모른 척하고 있지는 않으신가요?

결론 및 Action Item

이번 리팩토링의 핵심을 요약하자면 다음과 같습니다.

  • 타입 설계의 유연성: PartialOmit 조합을 통해 DB 스키마와 프론트엔드 간의 불일치를 해결했습니다.
  • 바이브 코딩의 재정의: AI는 생산성을 극대화하는 도구일 뿐, 코드의 주인은 여전히 개발자 자신이어야 합니다.
  • 유지보수의 핵심: any를 줄이고 타입을 구체화하는 것이 런타임 안정성과 유지보수 속도를 결정합니다.

당장 실행할 Action Item: 오늘 작성한 코드 중에서 가장 찜찜한 any 타입 하나를 골라, 위에서 언급한 유틸리티 타입을 활용해 구체적인 타입으로 교체해 보세요. 그 작은 변화가 여러분의 서비스를 더 단단하게 만들 것입니다.

Share this post