Typescript document의 Narrowing 파트를 참고하였다.
위의 코드에서 padding
이라는 변수에 주목하자. padding
은 number 또는 string 값을 갖는 유니언 타입으로 선언되었는데, 실제 함수 내에서는 padding: number
, padding: string
처럼 하나의 타입으로만 판단된다.
이는 typeof 라는 특별한 명령어를 이용하여 padding
변수의 타입을 좁혀준 결과이다. 이렇듯 추가적인 타입 체크나 할당을 이용하여 변수의 타입을 좀 더 작은 범위로 좁혀주는 것을 Narrowing 이라고 한다.
typeof
오퍼레이터는 변수의 타입 정보를 string으로 return해준다.
typeof
가 리턴값으로 가질 수 있는 타입들은 다음과 같다(모두 string type으로 return됨을 기억하자)
string
number
bigint
boolean
symbol
undefined
object
function
참고로 typeof null
은 "object"
를 리턴한다. 주의하자.
javascript에서 조건문으로 사용할 수 있는 것에는 &&
, ||
, if
, !
등이 있다.
보통 조건문의 condition 항목에는 true 또는 false 값을 갖는 boolean
이 들어가게 되는데, 만약 boolean이 아니라면 해당 값을 boolean으로 형변환을 시키게 된다.
false
로 변환되는 값들
0
NaN
(Not a Number)0n
(thebigint
version of zero)undefined
""
(empty string)
위의 값들을 제외한 나머지 값들은 모두true
로 간주된다.
이런식으로 Boolean 으로 형변환하는 것은
!!
) 를 이용하여 값을 Boolean으로 변환할 수 있다.!!
는 literal type(true
)을 갖는다는 것이다.
- moreRef- stack overflow : What is the !! operator in JS?
그렇다면, 글의 가장 처음에서 만난 printAll
함수에 이렇게 적용이 가능하다. 이 경우, string[]
type 만 첫번째 if
block에 들어가게 되면서 에러가 사라진다.
✔︎ truthiness narrowing을 사용하면서
0
이나empty string
등 의도치 않은 것까지 필터링해버릴 수도 있다. primitive type을 쓸 때는 주의하도록 하자.
x === y
라면, x와 y의 값이 같은 것은 물론이고, type또한 동일함을 의미한다. 이처럼 ===
, !==
, ==
, !=
를 사용하여 narrowing 을 할 수도 있다.
==
는===
보다는 조금 더 느슨하게 체크를 한다.x == null
은x === null || x === undefined
의 의미와 동일하다.
추가로
in
instanceof
assignment
유저가 type-guard를 직접 정의할 수도 있다. 이를 위해서는 type predicate 의 리턴 타입을 갖는 함수를 정의해야 한다.
위 함수에서는 pet is Fish
가 type predicate가 된다.
{parameter name} is {Type}
.isFish
의 호출을 통해 narrowing이 가능하다.narrowing을 진행하면서 고려하지 않은 사항들을 확인하기 위해 never
type을 이용할 수 있다.
never
은 존재해서는 안되는 타입으로 모든 타입에 할당이 가능하다(하지만 never
type에는 never
가 아니면 어떤 것도 할당이 불가하다).
never
를 사용한 예이다.
Shape
union에 Triangle
이라는 새로운 타입이 추가된다면, typescript는 에러를 감지한다.