만약 함수의 반환값이나 매개변수를 알 수 없다면 any 대신 unknown를 사용해야한다.
타입스크립트에서 타입은 다른 타입들과 부분 집합은 될 수 있지만 동시에 상위 집합이 될 수 없다.
하지만 any는 어떤 타입이든 상관없이 할당받을 수 있으며 반대로 할당이 될 수 있는 강력함을 가지고 있어 코드를 개발할 때 문제를 일으키는 원인이 될 수 있다. (모든 타입을 any로 바꾸고 타입 체커를 무용지물로 만들 수 있다.
)
any의 속성
- 1️⃣ 어떠한 타입이든 any에 할당
예)any = number
⭕️- 2️⃣ any 타입은 어떠한 타입으로도 할당이 가능 (never 제외)
예)number = any
⭕️
하지만 unknown은 any의 1️⃣ 번 속성은 만족하지만 2️⃣ 번 속성을 만족하지 않는다.
unknown의 속성
- 1️⃣ 어떠한 타입이든 unknown에 할당이 가능
예)unknown = number
⭕️- 2️⃣ unknown 타입은 어떠한 타입으로도 할당이 안됌 (unknown, any 제외)
예)number = unknown
❌
unknown에는 값을 할당할 수 있지만 unknown을 타입인 채로 값을 사용하면 오류가 발생한다.
같은 의미로 unknown 타입인 변수로 함수를 호출하거나 연산을 하려고해도 마찬가지이다.
그렇기 때문에 unknown은 사용하기 전 적절한 타입으로 변환할 수 있도록 강제해준다.
interface Feature {
id: number;
geometry: Geometry;
properties: unknown;
}
function isString(val: unknown): val is string {
return typeOf(val) === 'string'
}
function processValue(val: unknown) {
if (val instanceOf Date) {
val // 타입 가드 (instanceOf)를 통해 타입이 Date로 좁혀졌다.
} else if (isString(val)) {
val // 사용자 정의 타입 가드(is)를 통해 타입이 string으로 좁혀졌다.
}
}
unknown 타입이 도입되기 전에 {}
와 object
가 일반적으로 사용이 되었다.
둘 다 받을 수 있는 타입의 범위은 넓지만 unknown보다는 좁다.
{ } : null과 undefined을 제외한 모든 값을 포함
object: 객체와 배열을 포함한다. (string, boolean, number 제외)
최근에는 {}
을 사용하는 일이 드물지만 상황에 따라 null과 undefined 값을 받는게 불가능하다고 판단될 때에 unknown대신 {}
을 사용할 수 있다.