type-safe 를 어디까지 강제할 것인가
타입 안전성을 코드베이스 전체에 강제하는 것이 항상 이득인지, 우리 팀이 어떤 기준으로 강도를 조절하는지를 실제 경험 기반으로 정리한다.
TypeScript를 쓰면서 tsconfig.json의 strict: true를 켜는 순간, 코드베이스 전체가 빨간 줄로 뒤덮이는 경험을 해봤을 것이다. 이걸 다 고쳐야 하는가. 그 비용은 어디서 회수하는가. 우리가 지난 1년 동안 실제로 부딪히고 내린 판단을 기록한다.
타입을 강하게 쓸수록 좋은 이유
컴파일 타임에 잡히는 오류는 런타임에 잡히는 오류보다 처리 비용이 훨씬 낮다. 특히 리팩터링할 때 타입이 이동 경로를 안내하는 역할을 한다. any가 없는 코드는 자동 완성과 참조 추적이 정확하게 동작해 코드를 읽는 속도도 빨라진다.
강제하면 역효과가 나는 지점
빠른 프로토타입 단계: 아직 구조가 확정되지 않은 코드에 엄격한 타입을 붙이면 타입을 고치는 데 시간을 더 쓴다. 이 단계에서는 any나 unknown으로 대충 잡아두고 구조가 안정된 다음에 강화하는 게 낫다.
외부 API 응답: 외부에서 받는 JSON은 실제로 타입이 보장되지 않는다. zod나 비슷한 런타임 검증 라이브러리 없이 타입만 선언하면 거짓 안전감을 준다. 런타임 검증과 타입은 함께 써야 한다.
테스트 픽스처: 테스트용 목 데이터에 실제 타입을 그대로 강제하면 관련 없는 필드를 모두 채워야 해서 테스트가 길어진다. 여기서는 Partial<T>나 테스트 전용 타입을 쓴다.
우리가 지금 쓰는 기준
- 프로덕션 코드:
strict: true,noImplicitAny: true - 외부 입력 처리 레이어: 런타임 스키마 검증 필수, 타입은 검증 결과에서 추론
- 테스트 코드:
strict는 유지하되 픽스처는Partial허용 - 타입 단언(
as): PR에서 이유 없는as unknown as X패턴은 리뷰에서 반려
요점
타입 안전성은 목표가 아니라 도구다. 어디에 얼마나 쓸지를 팀이 의식적으로 결정하지 않으면, 규칙이 있어도 코드베이스 곳곳에 any가 쌓이거나 반대로 타입을 맞추느라 로직을 못 전진시키게 된다.
— by mings