📑 목차
타입스크립트를 쓰다 보면 타입을 미리 알 수 없거나, 유연하게 처리해야 할 상황이 생긴다. 이때 사용할 수 있는 것이 any와 unknown이다. 두 타입 모두 모든 값을 허용한다는 공통점이 있지만, 안정성 면에서 큰 차이가 있다.
1. Any 타입 (치트키)
any 타입은 타입스크립트의 모든 타입 검사를 무력화시키는 일종의 치트키(Cheat Key) 같은 타입이다.
1-1. 무제한의 자유
일반적으로 타입스크립트는 초기화된 값을 기준으로 타입을 추론하거나, 명시된 타입 외의 값을 넣으면 에러를 뱉는다. 하지만 any를 쓰면 어떤 타입의 값이든 할당할 수 있다.
let anyVar: any = 10;
anyVar = "hello"; // 문제없음
anyVar = true; // 문제없음
anyVar = {}; // 문제없음
심지어 해당 값에 어떤 메서드를 쓰든, 어떤 연산을 하든 터치하지 않는다.
anyVar.toUpperCase(); // 런타임에 에러가 날 수도 있지만, 컴파일은 통과됨
anyVar.toFixed();
anyVar.a;
1-2. 모든 타입에 할당 가능
any 타입의 변수는 다른 정적인 타입(number 등)의 변수에도 자유롭게 할당할 수 있다.
let anyVar: any = 10;
let num: number = 20;
num = anyVar; // ❌ 문제 발생! num은 number 타입인데 any가 들어와 버림
1-3. Any의 위험성
any는 편해 보이지만 매우 위험하다. 컴파일 시점에 에러를 잡지 못하고 런타임(실행 중)에 에러가 터질 수 있기 때문이다.
any를 남발하면 타입스크립트를 쓰는 이유가 사라진다. 따라서 정말 어쩔 수 없는 경우를 제외하고는 사용하지 않는 것을 강력히 권장한다.
2. Unknown 타입 (안전한 Any)
unknown 타입은 any와 비슷하게 모든 타입의 값을 저장할 수 있지만, 훨씬 더 안전하다.
2-1. 모든 값을 받을 수 있다
any처럼 변수에 어떤 타입의 값이든 넣을 수 있다.
let unknownVar: unknown;
unknownVar = "";
unknownVar = 1;
unknownVar = () => {};
2-2. 하지만 사용은 엄격하다
값을 넣을 때는 자유롭지만, 그 값을 사용하거나 다른 변수에 넣을 때는 엄격한 제한이 걸린다.
1) 다른 타입의 변수에 할당 불가unknown 타입의 값은 오직 any나 unknown 타입의 변수에만 할당할 수 있다.
let num: number = 10;
let unknownVar: unknown = 20;
// num = unknownVar; // ❌ 에러 발생 (Type 'unknown' is not assignable to type 'number')
2) 연산 및 메서드 사용 불가 값의 타입이 확실하지 않기 때문에 연산이나 메서드 호출도 막혀 있다.
let unknownVar: unknown = 30;
// unknownVar * 2; // ❌ 에러 발생
// unknownVar.toUpperCase(); // ❌ 에러 발생
정리하자면 unknown은 "값을 저장하는 행위"만 가능하고, 그 값을 사용하려면 반드시 타입을 확인하는 과정을 거쳐야 한다.
3. Unknown 타입 올바르게 사용하기 (타입 좁히기)
unknown 타입의 값을 사용하려면, 해당 값이 어떤 타입인지 확실히 검사해줘야 한다. 이를 타입 좁히기(Type Narrowing) 라고 한다.
let unknownVar: unknown = 10;
if (typeof unknownVar === "number") {
// 이 블록 안에서는 unknownVar가 number 타입으로 취급된다.
console.log(unknownVar * 2); // ✅ 정상 작동
}
조건문을 통해 타입이 확인되면, 타입스크립트는 해당 블록 내부에서 변수의 타입을 자동으로 추론해 준다.
요약
- Any 타입: 모든 검사를 무시하는 치트키. 타입 안정성을 해치므로 사용을 지양해야 한다.
- Unknown 타입: 모든 값을 저장할 수 있지만, 사용하려면 타입을 검사해야 한다.
any보다 안전하다. - 결론: 변수의 타입을 미리 알 수 없다면
any대신unknown을 사용하는 것이 훨씬 안전하다.
