<script>
function hello(x :number | string){
return x + 1
// Operator '+' cannot be applied to types 'string | number' and 'number'
}
</script>
위와 같은 함수를 실행시키려 할 때 에러가 발생한다.
number | string과 같은 유니온 타입에는 일반적으로 조작을 못하게 막아둬서 그렇다.
이럴경우 Narrowing과 Assertion을 사용한다.
<script>
function hello(x :number | string){
if (typeof x === 'number') {
return x + 1
}
else if (typeof x === 'string') {
return x + 1
}
else {
return 0
}
}
</script>
Type Narrowing은 if문과 typeof를 이용하여 x가 number 타입일 때의 값과 x가 string 타입일 때의 값을 정해주는 것이다.
타입이 확실하지 않을 때 생기는 부작용을 막기위한 장치인 것이다.
이때 typeof는 문자열을 반환하기 때문에 타입을 비교할 때 'number' 와 같이 쓰는것에 주의하자
또한 if문에 else {} 가 없으면 에러를 발생시킬 수 있다. return 하지않는 조건문이 있다면 나중에 버그가 생길 수 있어서 에러를 내주는 것이다.
Type Narrowing은 꼭 typeof를 쓸 필요는 없고 in, instanceof 키워드와 같이 타입을 하나로 확정지을 수 있는 코드면 가능하다.
<script>
function hello(x :number|string) {
let array :number[] = [];
array[0] = x as number
}
</script>
Type Assertion은 변수명 as 타입과 같이 사용하고 이 변수를 number 타입으로 생각해주세요 처럼 타입을 덮어씌워 준다.
하지만 Type Assertion을 쓸 때 주의할 것이 있다.
<script>
function hello(x :number | string){
return (x as number) + 1
}
console.log( hello('123') )
</script>
hello 함수에 '123'을 넣게되면 '1231'이 출력 될 것이다. 이처럼 as는 타입을 주장만 하는 것이고 실제로 타입을 바꿔주는 것은 아니다.
as를 사용하면 간편하지만 정확하게 코드를 짜기 위해서는 narrowing을 사용하도록 하자