blog

TypeScript unknown과 any의 차이

Front-end / TypeScript#TypeScript#unknown#any#타입 좁히기

any와 unknown은 둘 다 모든 값을 할당받을 수 있지만, 그 값을 사용할 때 큰 차이가 있다.

any: 타입 검사를 끈다

let value: any;

value = 5;
value = 'hello';
value.toUpperCase(); // 통과
value.someNonExistentMethod(); // 통과 → 런타임 에러

any는 타입 검사를 우회한다. 존재하지 않는 메서드를 호출해도 컴파일러가 막지 않고, any 값을 다른 타입 변수에 넣으면 그 오염이 코드 전체로 퍼진다.

unknown: 사용 전에 확인을 강제한다

let value: unknown;

value = 5;
value = 'hello';

value.toUpperCase(); // ❌ 'value' is of type 'unknown'

if (typeof value === 'string') {
  value.toUpperCase(); // ✅ string으로 좁혀진 뒤 사용
}

unknown은 "아직 무슨 타입인지 모른다"는 뜻이다. typeof, instanceof, in, 사용자 정의 타입 가드 등으로 타입을 좁힌 뒤에만 사용할 수 있다. 또한 unknown은 any와 unknown 이외의 타입 변수에 그대로 할당할 수 없다.

비교

특징anyunknown
모든 값 할당가능가능
바로 속성 접근·호출가능(검사 안 함)불가(컴파일 에러)
다른 타입 변수에 할당가능불가(좁힌 뒤 가능)
타입 안전성없음있음

언제 쓰나

unknown이 어울리는 곳은 외부에서 들어와 형태를 보장할 수 없는 값이다.

function parseJson(jsonString: string): unknown {
  return JSON.parse(jsonString);
}

function handleApiResponse(response: unknown) {
  if (typeof response === 'object' && response !== null && 'id' in response) {
    console.log('id:', response.id);
  }
}

catch (error)의 error도 useUnknownInCatchVariables(strict에 포함) 설정에서 unknown이다. 실무에서는 손으로 타입 가드를 쓰기보다 Zod 같은 스키마 검증 라이브러리로 unknown을 구체 타입으로 바꾸는 경우가 많다.

any는 점진적 마이그레이션이나 타입 정의가 없는 라이브러리를 임시로 다룰 때처럼 의도적으로 검사를 끄는 경우에만 쓴다. 가능하면 unknown을 기본으로 선택한다.