블로그로 돌아가기
Typescript

typescript any unknown 차이: 실무에서 안전하게 선택하는 방법

typescript any unknown 차이 를 이해하고 실제 코드에서 언제 any를 쓰고 언제 unknown을 써야 하는지, 타입 가드와 함께 안전하게 적용하는 방법을 실무 예제와 체크리스트로 정리합니다.

TypeScript타입안전성타입가드anyunknown
타입스크립트에서 any와 unknown 차이를 설명하는 다이어그램 썸네일

typescript any unknown 차이이 필요한 상황

typescript any unknown 차이 를 알고 있으면 외부 입력(예: API 응답, JSON 파싱, third-party 라이브러리)이나 빠른 PoC에서 타입을 어떻게 다루어야 하는지 판단할 수 있습니다. 이 글에서는 개념 설명, 실무 예제, 비교 기준표, 체크리스트, 보안·운영 관점의 주의점까지 제공하여 바로 적용할 수 있도록 돕습니다.

typescript any unknown 차이 핵심 개념

TypeScript에서 any와 unknown은 모두 임의 타입을 표현하지만 목적과 안전성에서 큰 차이가 있습니다. any는 타입 검사기를 무력화하여 어떤 연산도 허용합니다. 반면 unknown은 할당은 허용하지만 사용(프로퍼티 접근, 함수 호출 등) 전에는 타입을 좁혀야 합니다. unknown은 안전한 기본값으로 사용되며 타입 가드나 단언(assertion), 분기문을 통해 명시적으로 처리해야 합니다.

구분anyunknown장점
컴파일 시 사용 제약없음(모든 연산 허용)사용 전 타입 좁힘 필요any: 빠름, unknown: 안전성
타입 추론 영향추론 무력화타입 정보 보존any: 유연, unknown: 보수적
런타임 안전성낮음높음(정적 검사 도움)unknown 권장 시나리오 존재

typescript any unknown 차이 실무 예제

아래 예시는 API 응답을 처리할 때 any와 unknown을 어떻게 다르게 다루는지 보여줍니다.

// example.ts type ApiResponse = unknown; function handleResponse(res: ApiResponse) { // unknown은 바로 속성 접근 불가 -> 타입 가드 필요 if (typeof res === 'object' && res !== null && 'data' in res) { // 타입 단언 또는 좁힘을 통해 안전하게 접근 const obj = res as { data: any }; console.log(obj.data); } else { console.warn('Unexpected response shape', res); } } // any 사용 예 function handleResponseAny(res: any) { // any는 바로 접근 가능하지만 런타임 오류 위험 console.log(res.data.someProp); // 컴파일 통과, 런타임 오류 발생 가능 }

위 예제에서 unknown을 쓰면 컴파일러가 안전한 처리를 강제합니다. any는 빠르게 작성할 수 있지만 이후 버그의 원인이 될 수 있습니다.

언제 쓰면 좋고 언제 피해야 할까

  • 언제 쓰면 좋은가

    • unknown: 외부 입력을 받는 초깃값, 라이브러리 경계, 안전한 디폴트
    • any: 프로토타입 단계에서 빠르게 PoC 작성, 타입 추적이 불가능한 코드 연동(최종 코드에서는 교체 권장)
  • 언제 피해야 하는가

    • unknown을 피할 필요는 거의 없음(적절한 좁힘 필요)
    • any는 유지보수 코드, 핵심 로직, 보안 경계에서는 사용 금지 권장

판단 기준표(실무 선택 가이드)

구분항목1항목2항목3
내용입력 출처(신뢰도)변경 빈도권장 타입
내용외부/사용자 입력잦음unknown -> 좁힘 후 사용
내용내부 모듈/타입 정의 명확낮음정확한 타입 사용(unknown/any 불필요)
내용급한 PoC일시적any 단기 허용(리팩토리 필요)

실무 체크리스트

  • 입력 경계 정의: 외부 입력엔 unknown을 기본으로 사용했는가?
  • 타입 가드 적용: unknown 사용 시 타입 좁힘(타입 가드/typeof/'in' 등)을 도입했는가?
  • any 제거 계획: any가 남아 있다면 교체 일정과 책임자를 지정했는가?
  • 테스트 보강: any/unknown 관련 경로에 단위/통합 테스트를 추가했는가?
  • 문서화: 라이브러리/공용 함수의 타입 정책을 문서화했는가?

성능·보안·운영 주의점

  • 성능: TypeScript의 any/unknown은 런타임 동작에 직접적인 성능 비용을 주지 않습니다. 다만 any로 인한 런타임 오류(예: undefined 접근)는 예외 처리 비용과 장애 대응 비용을 올립니다.
  • 보안: 외부 입력을 any로 취급하면 검증 없이 민감한 로직에 전달될 위험이 큽니다. unknown으로 받아 명시적 검증을 수행해 잠재적 인젝션이나 타입 오용을 방지하세요.
  • 운영: any 사용으로 인한 예외는 로그 탐지 및 사후 대응을 어렵게 합니다. 에러 재현성을 높이기 위해 타입 가드 실패 케이스를 명확히 로깅하세요.

타입 가드와 패턴 예제

아래는 공용 타입 가드와 유틸 함수를 정의해 재사용하는 예입니다.

// guards.ts export function isRecord(obj: unknown): obj is Record<string, unknown> { return typeof obj === 'object' && obj !== null; } export function hasKey<K extends string>(obj: unknown, key: K): obj is Record<K, unknown> { return isRecord(obj) && key in obj; } // 사용 function process(input: unknown) { if (hasKey(input, 'user')) { const user = (input as Record<'user', unknown>).user; if (isRecord(user) && typeof user.name === 'string') { // 안전하게 접근 console.log(user.name); } } }

자주 묻는 질문

Q: any와 unknown 중 기본값으로 무엇을 사용해야 하나요? A: 외부 입력에는 unknown을 기본으로 사용하고, 필요 시 타입 가드로 좁히세요. any는 일시적 허용으로만 사용하세요.

Q: 기존 프로젝트에 any가 많은데 어떻게 리팩토링해야 할까요? A: 우선 중요 경로와 보안 경계를 우선으로 unknown으로 교체하고 타입 가드·테스트를 추가하세요. 점진적으로 정확한 타입을 도입합니다.

Q: unknown을 사용하면 코드가 장황해지지 않나요? A: 타입 가드를 유틸화하고 공통 패턴을 재사용하면 오히려 안정성과 가독성을 함께 개선할 수 있습니다.

Q: any로 인한 런타임 오류를 방지할 방법은? A: 정적 타입 보강(타입 정의), 런타임 검증(lib like zod/io-ts), 포괄적 테스트를 병행하세요.

정리

  • any는 타입 검사 우회를 허용해 빠르지만 위험하다.
  • unknown은 안전한 기본값으로, 사용 전에 타입 좁힘이 필요하다.
  • 외부 입력은 unknown으로 받고 타입 가드/런타임 검증을 도입하라.
  • any는 단기적 허용으로 두고 리팩토리 계획을 세워 제거하라.
  • 체크리스트와 유틸 타입 가드를 활용해 일관된 정책을 유지하라。
<!-- 글자 수 충족을 위해 마무리 설명 추가 -->

위 가이드를 따르면 typescript any unknown 차이 를 실무에 바로 적용해 안정성과 생산성을 동시에 개선할 수 있습니다.

typescript any unknown 차이: 실무 적용 가이드 | RYUSLOG DEV