← 모든 글

type-safe 를 어디까지 강제할 것인가

타입 안전성을 코드베이스 전체에 강제하는 것이 항상 이득인지, 우리 팀이 어떤 기준으로 강도를 조절하는지를 실제 경험 기반으로 정리한다.

TypeScript를 쓰면서 tsconfig.jsonstrict: true를 켜는 순간, 코드베이스 전체가 빨간 줄로 뒤덮이는 경험을 해봤을 것이다. 이걸 다 고쳐야 하는가. 그 비용은 어디서 회수하는가. 우리가 지난 1년 동안 실제로 부딪히고 내린 판단을 기록한다.

타입을 강하게 쓸수록 좋은 이유

컴파일 타임에 잡히는 오류는 런타임에 잡히는 오류보다 처리 비용이 훨씬 낮다. 특히 리팩터링할 때 타입이 이동 경로를 안내하는 역할을 한다. any가 없는 코드는 자동 완성과 참조 추적이 정확하게 동작해 코드를 읽는 속도도 빨라진다.

강제하면 역효과가 나는 지점

빠른 프로토타입 단계: 아직 구조가 확정되지 않은 코드에 엄격한 타입을 붙이면 타입을 고치는 데 시간을 더 쓴다. 이 단계에서는 anyunknown으로 대충 잡아두고 구조가 안정된 다음에 강화하는 게 낫다.

외부 API 응답: 외부에서 받는 JSON은 실제로 타입이 보장되지 않는다. zod나 비슷한 런타임 검증 라이브러리 없이 타입만 선언하면 거짓 안전감을 준다. 런타임 검증과 타입은 함께 써야 한다.

테스트 픽스처: 테스트용 목 데이터에 실제 타입을 그대로 강제하면 관련 없는 필드를 모두 채워야 해서 테스트가 길어진다. 여기서는 Partial<T>나 테스트 전용 타입을 쓴다.

우리가 지금 쓰는 기준

  • 프로덕션 코드: strict: true, noImplicitAny: true
  • 외부 입력 처리 레이어: 런타임 스키마 검증 필수, 타입은 검증 결과에서 추론
  • 테스트 코드: strict는 유지하되 픽스처는 Partial 허용
  • 타입 단언(as): PR에서 이유 없는 as unknown as X 패턴은 리뷰에서 반려

요점

타입 안전성은 목표가 아니라 도구다. 어디에 얼마나 쓸지를 팀이 의식적으로 결정하지 않으면, 규칙이 있어도 코드베이스 곳곳에 any가 쌓이거나 반대로 타입을 맞추느라 로직을 못 전진시키게 된다.

— by mings