Typescript document의 Narrowing 파트를 참고하였다.

위의 코드에서 padding 이라는 변수에 주목하자. padding은 number 또는 string 값을 갖는 유니언 타입으로 선언되었는데, 실제 함수 내에서는 padding: number, padding: string 처럼 하나의 타입으로만 판단된다.
이는 typeof 라는 특별한 명령어를 이용하여 padding 변수의 타입을 좁혀준 결과이다. 이렇듯 추가적인 타입 체크나 할당을 이용하여 변수의 타입을 좀 더 작은 범위로 좁혀주는 것을 Narrowing 이라고 한다.
typeof 오퍼레이터는 변수의 타입 정보를 string으로 return해준다.
typeof가 리턴값으로 가질 수 있는 타입들은 다음과 같다(모두 string type으로 return됨을 기억하자)
stringnumberbigintbooleansymbolundefinedobjectfunction
참고로 typeof null은 "object"를 리턴한다. 주의하자.
javascript에서 조건문으로 사용할 수 있는 것에는 &&, ||, if, ! 등이 있다.
보통 조건문의 condition 항목에는 true 또는 false 값을 갖는 boolean이 들어가게 되는데, 만약 boolean이 아니라면 해당 값을 boolean으로 형변환을 시키게 된다.
false로 변환되는 값들
0NaN(Not a Number)0n(thebigintversion 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의 의미와 동일하다.
추가로
ininstanceofassignment
유저가 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는 에러를 감지한다.