Studying/TypeScript

TypeScript - any 타입, unknown 타입

creamymood 2025. 6. 8. 15:10

 

출처 : 한 입 크기로 잘라먹는 타입 스크립트


any와 unknown 둘 다 상위 타입으로, 느낌이 비슷했다...

특히 any는 뭔가. 어떤 것이든~ 이런 느낌이라, 이해하기 쉬웠는데

unknown은 이해하기가 어려웠는데, 아래처럼 이해해본다면 다소 쉬웠다.

더보기

any의 비유:

나 다 알아서 할 수 있어! 걱정 말고 그냥 줘~
→ 무조건 받아서 아무 데나 막 씀. 설사 틀려도 컴파일러는 모름.

  • 예시: 친구한테 “이거 써!” 하고 연필인지 칼인지도 안 보고 막 쓰는 느낌
  • 타입스크립트 입장에서 보면: “그래, 니 마음대로 해. 책임도 니가 져.”

 

 unknown의 비유:

일단 받을게, 근데 뭔지 확인하고 써볼게!
→ 뭐든 받을 수는 있지만, 쓸 땐 조심해서 검사하고 써야 함.

  • 예시: 누군가 상자를 줬을 때, "일단 고마워~ 그런데 열어보고 칼이면 조심하고, 연필이면 써야지!"
  • 타입스크립트 입장에서 보면: “받을 수는 있지만, 진짜 쓸 땐 뭔지 확인부터 해.”

 요약 문장

 any는 무조건 신뢰하고 막 써도 되는 친구 같지만, 사실 사고를 많이 치는 친구
 unknown은 신중한 친구라 뭐든 받아주되, 꼭 확인하고 처리하는 책임감 있는 친구

 


1. any 타입

any타입은 타입스크립트에만 있는 특별한 타입으로,

타입 검사를 하지 않는 특수한 키다.

모든 타입을 의미하며, 어떠한 타입의 값도 할당할 수 있는 강력한 타입이다.

 

외부자원을 이용해 개발할 때, 또는 불가피하게 타입 단언을 할 수 없을 때 등등 유용하다.

 

외부 자원을 이용해서 개발하거나, 뭐 아무튼 범용적으로 사용되어야 할 (뭐.. 변동이 많은? 이라고 해석하면 쉬울 것 같다)

변수가 있다고 생각해보자.

let anyVar = 10;
anyVar = "hello"; // 오류 발생!

타입스크립트는 변수를 초기화 할 때, 기존의 타입으로 추론을 하기 때문에 이 경우는 오류가 생긴다..

(number로 생각했기 때문에 문자열 안됌)

 

이럴때, any라는 치트키를 사용하면 된다.

let anyVar: any = 10;
anyVar = "hello";

anyVar = true;
anyVar = {};

anyVar.toUpperCase();
anyVar.toFixed();
anyVar.a;

앞서 말했듯 any는 타입 검사를 받지 않기 때문에 어떠한 값을 할당할 수도 있고, 다양한 타입의 메서드도 호출해서 사용해도 문제가 없다.

 

let anyVar: any = 10;
anyVar = "hello";

let num: number = 10;
num = anyVar;

이런식으로 number 타입의 num에.. any타입도 할당 가능.

 

하지만, 타입 검사가 행해지지 않는 이러한 치트키 답게 (모든 걸 무시하는..)

자유로운 대신 런타임 오류가 있을 수도 있고, 위험한 코드 답게, 타입스크립트를 쓰는 이유가 없어지니

불가피한 상황 이에외에는 지양하는 것이 좋다.

 

* 강한 타입 시스템의 장점을 유지하기 위해 Any 사용을 엄격하게 금지하려면, 컴파일 옵션 "noImplicitAny": true를 통해 Any 사용 시 에러를 발생시킬 수 있다.


2. unknown 타입

unknown은 any와 비슷하지만 보다 안전한 타입이다. (타입 가드나, 타입 단언이 필요하다 : 사용할 때, 타입을 정해줘야 한다)

* any는 어떤 값에든 할당이 가능하지만, unknown을 다른 타입에는 할당할 수 없다.

 

→ unknown에는 어떤 값이든 할당이 가능하다

let unknownVar: unknown;

unknownVar = "";
unknownVar = 1;
unknownVar = () => {};

 

하지만 반대로는 안된다.

다른 값에 unknown을 할당은 안됌

let num: number = 10;
(...)

let unknownVar: unknown;
unknownVar = "";
unknownVar = 1;
unknownVar = () => {};

num = unknownVar; // 오류 !

 (앞서 살펴본 any는 가능했음)

let a: any = 123
let u: unknown = 123

let v1: boolean = a // 모든 타입(any)은 어디든 할당할 수 있습니다.
let v2: number = u // 알 수 없는 타입(unknown)은 모든 타입(any)을 제외한 다른 타입에 할당할 수 없습니다.
let v3: any = u // OK!
let v4: number = u as number // 타입을 단언하면 할당할 수 있습니다.

또 앞서 살펴본 any랑 달리, unknown은 다른 타입의 메서드를 호출해서 사용도 안되고, 연산에도 참여할 수 없다.

 

정리하자면, unknown 타입은 모든 값을 할당 받을 수는 있지만, 반대로 어떤 타입에도 unknown을 할당할 수는 없고, 

모든 연산이나 메서드도 호출이 불가하다. 

 

결국 아직 당장 어떤 값을 받을지 모를 때, 그냥 오직 값을 저장하는 행위만 할 수 있다.

 

참고로 unknown을 예를들어 number나 특정 타입으로 사용하고 싶은 경우

추후에 다룰 타입 좁히기라던지, 타입 단언으로써 사용할 수 있다.

if (typeof unknownVar === "number") {
	// 이 조건이 참이된다면 unknownVar는 number 타입으로 볼 수 있음
  unknownVar * 2;
}

출처 : 한 입 크기로 잘라먹는 타입스크립트, 한눈에 보는 타입 스크립트