[Effective Typescript - 아이템 42] 모르는 타입의 값에는 any 대신 unknown을 사용하기

Song·2022년 3월 1일
0
post-custom-banner

만약 함수의 반환값이나 매개변수를 알 수 없다면 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은 사용하기 전 적절한 타입으로 변환할 수 있도록 강제해준다.

코드 예제 💻

1. interface에서 값의 타입이 분명하지 않을 때

interface Feature {
	id: number;
  	geometry: Geometry;
  	properties: unknown;
}

2. typeguard를 통한 변환

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 타입이 도입되기 전에 {}object가 일반적으로 사용이 되었다.
둘 다 받을 수 있는 타입의 범위은 넓지만 unknown보다는 좁다.

{ } : null과 undefined을 제외한 모든 값을 포함
object: 객체와 배열을 포함한다. (string, boolean, number 제외)

최근에는 {}을 사용하는 일이 드물지만 상황에 따라 null과 undefined 값을 받는게 불가능하다고 판단될 때에 unknown대신 {}을 사용할 수 있다.

요약

  • unknown은 사용자가 타입 체크를 하도록 강제하기 때문에 어떠한 값의 타입을 모른다면
    any 보단 unknown를 사용하는 것이 안전하다.
  • unknown, {}, object의 차이점을 이해해야한다.

참고

profile
Learn From Yesterday, Live Today, Hope for Tomorrow
post-custom-banner

0개의 댓글