function range(start: number, limit: number) {
const out = [] // any[]로 선언됨.
for (let i = start; i < limit; i++) {
out.push(i)
}
return out // 반환 타입이 number[]로 추론됨.
}
조건문에서는 분기에 따라 타입이 변할 수 있다.
let val // 타입이 any
if (Math.random() < 0.5) {
val = /hello/
val // 타입이 RegExp
} else {
val = 12
val // 타입이 number
}
val // 타입이 number | RegExp
변수의 초깃값이 null인 경우에도 any의 진화가 일어난다. 보통 try/catch 블록 안에서 변수를 할당할 경우 나타난다.
let val = null // 타입이 any
try {
somethingDangerous()
val = 12
val // 타입이 number
} catch (e) {
console.warn('alas'!)
}
val // 타입이 number | null
이런 식으로 any 타입을 명시하지 않았는데도 any 타입으로 선언되는 것을 암시적 any(implicit any)라고 한다.
반대로 명시적으로 any를 선언하면 타입이 그대로 유지된다.
let val: any // 타입이 any
if (Math.random() < 0.5) {
val = /hello/
val // 타입이 any
} else {
val = 12
val // 타입이 any
}
val // 타입이 any
다음처럼 암시적 any 상태에서 변수에 어떠한 할당도 하지 않고 사용하려고 하면 암시적 any 오류가 발생한다.
function range(start: number, limit: number) {
const out = []
// ~~~ 'out' 변수는 형식을 확인할 수 없는 경우 일부 위치에서 암시적으로 'any[]' 형식이다.
if (start === limit) {
return out
// ~~~ 'out' 변수는 암시적으로 'any[]' 형식이 포함된다.
}
for (let i = start; i < limit; i++) {
out.push(i)
}
return out
}
any 타입의 진화는 암시적 any 타입에 어떤 값을 할당할 때만 발생한다.
다음 forEach 안의 화살표 함수는 추론에 영향을 미치지 않는다.
function makeSquares(start: number, limit: number) {
const out = []
// ~~~ 'out' 변수는 일부 위치에서 암시적으로 'any[]' 형식이다.
range(start, limit).forEach((i) => {
out.push(i * i)
})
return out
// ~~~ 'out' 변수는 암시적으로 'any[]' 형식이 포함된다.
}
루프로 순회하는 대신, 배열의 map, filter 메서드를 통해 단일 구문으로 배열을 생성해 any 전체를 진화시키는 방법을 생각해볼 수 있다.