
어떤것이든 들어올 수 있는 타입입니다.
무심코 any를 남용하게 되면, 전체적인 타입 시스템에 문제가 발생할 수도 있습니다. 그래서 정확하게 알고 쓰는 것이 중요합니다.
function returnAny(message): any {
console.log(message);
}
const any1 = returnAny('리턴은 아무거나');
any1.toString(); // Type적인 Error가 발생하지 않습니다.
any 타입은 어떤 타입이여도 상관없는 타입.이렇게 모르는 상태 일 때,
'아무것도 할 수 없다'의 의미가 아니고,'어떤 것이듯 할 수 있다'라는 의미를 가지는 것이anyType입니다.
any타입을 최대한 쓰지 않는 것이 타입시스템을 최대한 안전하게 유지하고,
이 코드를 사용하려는 사람들에게 정확한 가이드를 줄 수 있는 것입니다.
위 예시 코드를 다시 보면...

console.log만 출력하는 일을 하고 있습니다. 그래서 returnAny 매개변수에는 number타입이나 string 타입 등 다양한 타입들이 들어올 수 있는 함수입니다. 이런 message 매개변수는 정말로 any 타입일 수 있습니다.any 일 것이라고 추론합니다. 혹은 모른다고 판단합니다.
any타입이라고 명시하면 에러가 사라집니다.TypeScript가 any타입으로 추론하지만, 개발자가 명시적으로 적지 않으면 에러를 발생시키는 TypeScript 옵션을 "noImplicitAny": true 이라고 합니다."strict": true 로 설정하고 사용하고 있기 때문에 strict와 관련된 옵션인 "noImplicitAny" 도 true 상태입니다.
any는 계속해서 개체를 통해 전파된다는 것을 코드를 통해 확인해보겠습니다.
let looselyTyped: any = {};
const d = looselyTyped.a.b.c.d;
.a, .b, .c, .d 를 해도 에러가 발생하지 않습니다. 그리고 그 결과도 any 타입이 된 변수 d에 들어갑니다. 이런식으로 any가 개체를 통해서 전파됩니다.function leakingAny(obj: any) {
const a = obj.num; // num도 any이고 그 값을 받는 변수 a도 any타입이 됩니다.
const b = a + 1; // any 타입과의 덧셈결과를 저장하는 변수 b도 any타입이 됩니다.
return b;
}
const c = leakingAny({num: 0}); // 반환값을 저장하는 변수 c도 any타입이 됩니다.
// 하지만 c가 number로 규정이 되어서 나와야 하는것이 우리의 목표입니다.
const d: string = c.indexOf('0'); // 아무 Error도 발생하지 않았습니다.
any타입이지만, .indexOf() 함수를 가지고 있지 않은 타입도 존재합니다. 예를 들어 c 에 string 이 온다면 더 함수는 동작하지만, number가 온다면 Error가 발생해야하는 상황입니다. 즉, any로 인해 명확하지 않습니다.우리는 위코드에서 누수를 막을 수 있습니다.

function leakingAny(obj: any) {
const a: number = obj.num; // a의 타입을 number로 지정하면 여기서부터 누수를 막을 수 있습니다.
const b = a + 1; // 변수 b도 any타입에서 number타입으로 바뀌었습니다.
return b;
}
const c = leakingAny({num: 0}); // c도 any타입에서 number타입으로 바뀌었습니다.
// 하지만 c가 number로 규정이 되어서 나와야 하는것이 우리의 목표입니다.
const d: string = c.indexOf('0'); // Error

number에는 .indexOf()함수가 없으므로 Error를 발생시켜 타입의 착각으로 인한 잘못된 함수의 사용을 미리 막았습니다.위처럼
any타입을 명확한 타입으로 지정해 줄수도 있지만, 사실 더 좋은 방법은 obj를 사용하기 전에 '타입가드'를 통해 갈라내서 타입을 지정되도록 하는unknown을 사용하는 것을 더 추천합니다.
any가 타입의 불안정한 요소를 주는 부분을 조금이나마 해소하고자 나온 대체자라고 생각하면 좋을 것 같습니다.
TypeScript 3.0에서 unknown 타입이 도입되었습니다.
unknown 타입은 단어의 뜻과 동일하게 '알 수 없다, 모른다'라는 의미를 가집니다.
unknown 타입은 any 타입과 동일하게 모든 값을 허용하지만, 할당된 값이 어떤 타입인지 모르기 때문에 함부로 프로퍼티나 연산을 할 수 없습니다.

declare const maybe: unknown;
// 'maybe' could be a string, object, boolean, undefined, or other types
const aNumber: number = maybe; // Error // Type 'unknown' is not assignable to type 'number'.
if (maybe === true) {
// TypeScript knows that maybe is a boolean now
const aBoolean: boolean = maybe;
// So, it cannot be a string
const aString: string = maybe; // Type 'boolean' is not assignable to type 'string'.
}
if (typeof maybe === "string") {
// TypeScript knows that maybe is a string
const aString: string = maybe;
// So, it cannot be a boolean
const aBoolean: boolean = maybe; // Type 'string' is not assignable to type 'boolean'.
}
typeof 키워드는 runtime 에 어떤 특정한 변수나 개체에 그 타입을 검사합니다. 이렇게 타입검사를 통하여 타입가드 를 해줄 수 있습니다.