narrowing
Boolean, !!literalBoolean
narrowing이란 무엇인가?
ad. narrow ; 좁은, 이라는 뜻
함수 내부에서 들어온 인자에 대한 type검사를 하거나 아무튼 조건을 좁혀 특정 행동을 할 수 있게
해주는 것을 통칭해 narrowing한다고 한다.
즉 버그가 생겨날 여지를 줄이자는 것이 취지이다. typescript에서는 이를 어떻게 하는지 확인해보자.
function printAll(strs:string | string[] | null){
if(strs && typeof strs === 'object'){
for(const s of strs){
console.log(s);
}
}else if (typeof strs === 'string'){
console.log(strs);
console.log('typeof input: ',typeof strs);
}
}
printAll('aaa');
위 코드를 보게되면 인자는 함수에 들어가자마자 if문을 통과해야만 한다.
printAll에 들어올 수 있는 인자는 문자열, 문자열로 이루어진 배열, null 값이 전부이다.
JS에서 배열은 객체로 만들어진 유사 배열이므로 배열은 객체 타입입니다.
여기에서 한 가지 알아두어야 할 점이 있다.
JS에서 boolean으로써 적용되는 것들이 무엇인가에 대한 것이다.
true, false만 boolean으로 받는 것이 아니기 때문에 이를 짚고 넘어가야 한다.
아래는 TS에서 알려주는 JS의 boolean으로써 작동하는 type들이다.
0 // 0이아닌 숫자는 true
NaN // false
"" (the empty string) // false
0n (the bigint version of zero) // false
null // false
undefined // false
이정도는 다들 알고 있지만
function printAll(strs: string | string[] | null) {
// !!!!!!!!!!!!!!!!
// DON'T DO THIS!
// KEEP READING
// !!!!!!!!!!!!!!!!
if (strs) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
}
}
}
이러한 경우를 생각해보자.
if문을 최상단으로 올려 narrowing한다고 하자.
strs에 인자로써 ""가 들어오게 된다면 이는 string으로써 type검사를 통과해
함수로 들어오게 된다.
strs는 if문을 만나게되고 strs는 JS에서 false 값이므로 if를 통과하지 못하게 된다.
즉 타입 검사는 통과하고 if는 통과하지 못하는 함수인 것이다.
개발자 입장에서는 뭐 그럴 수 있지만 사용자에게 보여지는 앱의 경우 "" 입력 자체를 차단해야 한다.