타입스크립트의 타입은 변수를 선언할 때 결정된다. 하지만 any 타입과 관련해서 예외인 상황이 있습니다.
아래 예제가 바로 그러한 상황입니다.
|
function range(start: number, limit: number) {
const out = []; // any[]
for (let i = start; i < limit; i++ ){
out.push(i);
}
return out; // 반환 타입이 number[]로 추론됨.
}
|
out의 타입은 최초 변수가 선언되었을 때, any[]로 추론되었지만 number 타입을 push 한 순간부터 타입은 number[]로 진화(evolve)합니다.
타입의 진화는 타입 좁히기와는 다릅니다. 배열에 다양한 타입 요소를 넣으면 배열의 타입이 확장되면서 진화합니다.
|
const result = []; // any[]
result.push('a'); // string[]
result.push(1); // (string | number) []
|
또한 조건문에서는 분기에 따라 타입이 진화합니다.
|
let val; // any
if(Math.random() < 0.5){
val = /hello/
val; //타입이 RegEx
} else{
val = 12;
val;//타입이 number
}
console.log(val) // 타입이 RegEx | number
let val2 = null;
try{
someDangerousWork();
val2 = 12; // number
val2 // number
}catch(e){
console.warn(e);
val2 // number | null
}
val2; // number | null
|
하지만 변수 선언 시 타입을 any로 명시하면 any의 진화는 더 이상 일어나지 않습니다.
|
let val: any; // any
val = 12 // any
|
암시적 any 상태인 변수에 어떠한 할당도 하지 않고 사용하려고 하면 암시적 any 오류가 발생합니다.
|
function range(start: number, limit: number) {
const out = [];
// 오류 Variable 'out' implicitly has type 'any[]' in some locations where its type cannot be determined.(7034)
if(start === limit){
return out; // 오류 Variable 'out' implicitly has an 'any[]' type.(7005)
}
for (let i = start; i < limit; i++){
out.push(i);
}
return out;
}
|
any 타입의 진화는 암시적 any 타입에 어떤 값을 할당할 때만 발생합니다. 그리고 어떤 변수가 암시적 any 상태일 때 값을 읽으려고 하면 오류가 발생합니다.
암시적 any 타입은 함수 호출을 거쳐도 진화하지 않습니다. 아래 예제를 통해 확인할 수 있습니다.
|
function range(start: number, limit: number) {
const out = [];
// 오류 Variable 'out' implicitly has type 'any[]' in some locations where its type cannot be determined.(7034)
if(start === limit){
return out; // 오류 Variable 'out' implicitly has an 'any[]' type.(7005)
}
for (let i = start; i < limit; i++){
out.push(i);
}
return out;
}
function makeSquares(start: number, limit: number){
const out = [];
//Variable 'out' implicitly has type 'any[]' in some locations where its type cannot be determined.
range(start, limit).forEach(i =>{
out.push(i * i);
});
return out;
//Variable 'out' implicitly has an 'any[]' type.(7005)
}
|
* 일반적인 타입들은 정제되기만 하는 반면, 암시적 any와 any[] 타입은 진화할 수 있습니다. 이러한 동작이 발생하는 코드를 인지하고 이해할 수 있어야 합니다.
* any를 진화시키는 방식보다 명시적 타입 구문을 사용하는 것이 안전한 타입을 유지하는 방법입니다.
'IT' 카테고리의 다른 글
| Effective Typescript - 43 - 몽키 패치보다는 안전한 타입을 사용하기 (0) | 2022.01.24 |
|---|---|
| Effective Typescript - 42 - 모르는 타입의 값에는 any 대신 unknown을 사용하기 (0) | 2022.01.24 |
| Effective Typescript - 40 - 함수 안으로 타입 단언문 감추기 (0) | 2022.01.24 |
| Effective Typescript - 39 - any를 구체적으로 변형해서 사용하기 (0) | 2022.01.24 |
| Effective Typescript - 38 - any 타입은 가능한 좁은 범위에서만 사용하기 (0) | 2022.01.24 |