Engineering

TypeScript: any와의 전쟁을 끝내며

Mike발행일 2026년 1월 26일읽는 시간 약 3

TypeScript: 이제 제발 'any' 좀 그만 씁시다

솔직히 고백합시다. 프로젝트 마감 기한 다가오면 빨간 줄 뜨는 거 귀찮아서 as any 슬쩍 넣은 적 있다, 없다? 저도 찔립니다. 하지만 2026년의 TypeScript는 핑계 댈 수 없을 만큼 똑똑해졌고, 도구들도 좋아졌습니다. 이제는 진짜로 any 없는 세상을 만들 수 있습니다.

any가 왜 그렇게 나쁜가?

"작동만 하면 되지, 뭘 그렇게 까다롭게 구냐?" 이 말이 유효한 건 혼자서 토이 프로젝트 할 때까지입니다. 팀 프로젝트에서, 그것도 6개월 뒤에 누군가 내 코드를 수정해야 할 때 any가 얼마나 무서운지 아세요?

any는 TypeScript의 타입 시스템을 완전히 무력화시킵니다. 컴파일러가 "나는 이 변수에 대해 아무것도 모릅니다"라고 손을 드는 거예요. 그 순간부터 자동 완성도 안 되고, 타입 체크도 안 되고, 리팩토링할 때 찾을 수도 없습니다.

더 무서운 건 any전염성입니다. 함수 하나에 any를 넣으면, 그 함수의 반환값을 쓰는 모든 코드가 사실상 JavaScript가 됩니다. 한 부분의 타입이 무너지면 도미노처럼 전체가 무너집니다.

실제로 프로덕션 에러의 상당수가 타입 관련 런타임 에러입니다. "Cannot read properties of undefined"를 보신 적 있으시죠? 그 에러의 대부분은 타입이 제대로 추론되었다면 컴파일 시점에 잡혔을 겁니다.

1. satisfies: 꼼꼼함과 유연함을 동시에

이 녀석은 진짜 물건입니다. TypeScript 4.9에 도입된 이래, 가장 사랑받는 키워드 중 하나가 되었죠. 왜 그런지 설명해 드리겠습니다.

예전엔 타입 체크 하려고 변수에 타입을 명시하면(const colors: Record<string, RGB> = ...), TS가 멍청해져서 구체적인 값을 까먹어버렸거든요. "야, 이거 RGB 배열인 건 알겠는데, 정확히 [255, 0, 0]인지는 모르겠어." 라면서요.

이제 satisfies를 쓰면 TS한테 이렇게 말하는 겁니다. "이 규칙은 지키는지 확인해 줘. 근데 값 자체는 내가 쓴 그대로 기억해 줘." 덕분에 타입 안정성은 챙기면서, colors.red[0] 했을 때 자동 완성까지 완벽하게 지원됩니다. 이거 한 번 맛보면 옛날로 못 돌아갑니다.

어디서 진짜 유용한가?

  1. 설정 객체(Config Objects): API 키, 라우트 맵, 테마 색상 같은 설정 객체를 정의할 때 최고입니다. 타입 안전성을 보장하면서도, key 자동 완성이 됩니다.
  2. 라우트 정의: Next.js나 React Router에서 라우트를 정의할 때, 경로 문자열의 구체적인 값을 유지할 수 있습니다.
  3. 상수 열거: 상태값이나 옵션 목록을 정의할 때, as const와 함께 쓰면 더 강력합니다.

2. Zod: 런타임까지 지켜주는 보디가드

TS의 최대 약점은 "컴파일할 때만 센 척한다"는 거였죠. 빌드 시점에 아무리 타입을 꽁꽁 잠가놔도, 런타임에서 외부에서 들어오는 데이터에는 무방비입니다. API에서 이상한 데이터가 넘어오면 속수무책으로 터져버렸습니다.

그래서 요즘은 Zod가 필수 교양입니다.

"이 데이터는 무조건 문자열이고, 이메일 형식을 따라야 해." 라고 스키마를 짜두면, 실제 실행될 때 검사해 주는 건 물론이고 TS 타입까지 공짜로 만들어줍니다(z.infer). 스키마 따로, 인터페이스 따로 만들어서 관리하느라 고통받던 시절은 이제 안녕입니다. Single Source of Truth, 얼마나 아름답습니까.

실전에서 Zod를 쓰는 곳들

1. API 응답 검증: 외부 API의 응답을 Zod 스키마로 파싱하면, 예상과 다른 형식의 데이터가 들어왔을 때 즉시 에러를 잡을 수 있습니다. "필드가 빠져있다"거나 "숫자여야 하는데 문자열이 들어왔다" 같은 문제를 런타임 초반에 캐치합니다.

2. 폼 검증: React Hook Form과 Zod를 결합하면 환상의 조합이 됩니다. 스키마 하나로 프론트엔드 폼 검증과 서버 사이드 검증을 동시에 처리할 수 있습니다. Server Actions와 함께 쓰면 더 강력합니다.

3. 환경 변수 검증: 앱 시작 시 환경 변수를 Zod로 검증하면, 필수 변수가 빠져있을 때 앱이 아예 시작되지 않습니다. 프로덕션에서 "환경 변수가 없어서 500 에러"가 나는 최악의 상황을 예방합니다.

4. 데이터베이스 쿼리 결과: Supabase나 Prisma에서 가져온 데이터를 Zod로 추가 검증하면, ORM이 놓칠 수 있는 데이터 무결성 문제를 캐치합니다.

3. Template Literal Types: 문자열 가지고 놀기

함께 읽으면 좋은 글

Engineering

Next.js 인증 리다이렉트 루프 방지 플레이북: 로그인 UX와 보안을 동시에 지키는 운영 설계

2026-03-03
Engineering

Next.js 서버 액션 장애 복구 플레이북: 실패를 사용자 이탈로 번지지 않게 막는 실무 설계

2026-03-01

본문 작성/검수 원칙은 편집 원칙에서 확인할 수 있습니다.

← 목록으로 돌아가기