메인 콘텐츠로 바로가기

좋은 타입은 선언 수가 아니라 경계에서 나온다: enum 남용에서 벗어나기

TypeScript를 도입하면 흔히 이런 흐름이 생깁니다.

  • 공통 enum 파일을 만든다
  • 여러 계층(UI/API/도메인)에서 같이 쓴다
  • 처음엔 편한데, 시간이 갈수록 변경 영향이 커진다

문제는 타입이 많아서가 아니라, 타입이 있어야 할 경계에 있지 않기 때문입니다.


enum 남용이 왜 위험할까?

enum 자체가 문제는 아닙니다. 문제는 “전역 공용 enum”이 너무 많은 책임을 떠안는 순간 시작돼요.

예시:

  • API 응답 상태
  • UI 표시 상태
  • 도메인 비즈니스 상태

이 3가지를 같은 enum으로 묶으면, 한 군데 변경이 전체 레이어에 전파됩니다.

결과:

  • 관련 없는 파일까지 수정
  • 테스트 범위 확대
  • 사이드 이펙트 증가

경계를 기준으로 타입 나누기

실무에서는 타입을 “기술”이 아니라 “책임” 기준으로 나누는 게 안전합니다.

1) API 모델 (외부 계약)

  • 백엔드 계약에 맞춘 형태
  • 변경 가능성이 높고, 방어 코드 필요

2) 도메인 모델 (비즈니스 의미)

  • 제품 규칙이 담긴 내부 모델
  • UI와 API 사이의 중간 언어

3) UI 모델 (표현/상호작용)

  • 컴포넌트 렌더링에 최적화된 형태
  • 로딩/에러/선택 상태 등 화면 관점

핵심은 “같은 값”이라도 레이어가 다르면 타입도 분리한다는 점입니다.


실전 리팩터링 패턴

before: 공용 enum 하나로 모든 곳에서 사용

export enum Status { ACTIVE = 'ACTIVE', INACTIVE = 'INACTIVE', PENDING = 'PENDING', }

after: 레이어별 타입 분리 + 매핑 함수

// api/types.ts export type ApiUserStatus = 'ACTIVE' | 'INACTIVE' | 'PENDING' // domain/user.ts export type UserStatus = 'enabled' | 'disabled' | 'waiting' // ui/user.ts export type UserBadgeState = 'positive' | 'neutral' | 'warning' export function mapApiStatusToDomain(status: ApiUserStatus): UserStatus { if (status === 'ACTIVE') return 'enabled' if (status === 'INACTIVE') return 'disabled' return 'waiting' }

매핑 계층이 생기면 처음엔 코드가 늘어나는 것처럼 보이지만, 장기적으로는 변경 영향이 명확해지고 회귀 범위가 줄어듭니다.


면접에서 말할 포인트

  • “타입 안정성은 선언 개수보다 경계 설계가 중요하다고 봅니다.”
  • “API/도메인/UI 모델을 분리해 변경 전파 범위를 줄였습니다.”
  • “공용 enum 남용 대신 매핑 계층을 도입해 사이드 이펙트를 통제했습니다.”

이 답변은 단순 문법 지식보다 아키텍처 레벨 사고를 보여줍니다.


적용 체크리스트

  • 공용 enum이 3개 이상 레이어에서 재사용되고 있는가?
  • API 응답 타입이 UI 컴포넌트까지 직접 들어오는가?
  • 타입 변경 시 수정 파일 수가 비정상적으로 큰가?
  • 매핑 계층(anti-corruption layer)이 존재하는가?

2개 이상 Yes면 리팩터링 후보입니다.


포트폴리오에 어떻게 남길까?

이 주제는 “보여주기 어려운 리팩터링”이라서, 문서화 방식이 중요합니다.

추천 구성:

  1. 문제 상황(전역 enum 결합)
  2. 분리 전략(API/도메인/UI)
  3. 매핑 함수 도입 이유
  4. 변경 영향 축소 사례(정성/정량)

이렇게 정리하면 코드가 화려하지 않아도 설계 역량을 충분히 전달할 수 있습니다.


마무리

TypeScript에서 좋은 설계는 “타입을 많이 만드는 것”이 아니라 타입을 올바른 경계에 두는 것에서 시작합니다.

enum은 도구일 뿐이고, 진짜 품질은 경계와 의존 방향에서 결정됩니다.

이 관점이 잡히면 프론트엔드 코드의 변경 비용과 리뷰 난이도가 확실히 줄어듭니다.

댓글

developjik
All content is licensed under CC BY-NC-SA 4.0 unless otherwise noted.