[Typescript] any는 진화한다.

김유진·2023년 5월 16일
0

Effective-TypeScript

목록 보기
20/28
post-thumbnail

타입스크립트에서는 일반적으로 변수의 타입은 변수를 선언할 때 결정한다. 그 후, 정제되거나 변경되는 것은 어려우나, any 타입과 관련해서는 예외인 경우가 존재한다.

function range(start: number, limit: number) {
  const out = [];
  for (let i = start; i <limit; i++) {
    out.push(i);
  }
  return out;
}

out 타입은 처음에 암시적 any로 초기화되었는데, 반환 타입은 number[]로 등장한다. out의 타입은 any로 선언되었지만, number 타입의 값을 넣은 순간부터 타입이 진화한 것이다.
조건문에 따라서는 여러 값으로 진화할 수도 있다. 아래 코드를 보자.

const result = []; //타입이 any
result.push('a');
result //타입은 string[]
result.push(1);
result //타입은 (string|number)[]

any 타입의 진화는 noImplicitAny가 설정된 상태에서, 변수의 타입이 암시적으로 any인 경우에만 일어난다. 만약 명시적으로 any를 선언하게 된다면 타입이 그대로 유지된다.

만약, 암시적인 any 상태 변수로 둔 다음에 진화를 시키지도 않고, 단언을 시키지도 않는다면 오류가 발생한다.

function range(start: number, limit: number) {
  const out = [];
  if ( start === limit ) {
    return out;
  }
  for (let i = start ; i < limit ; i++) {
    out.push(i);
  }
  return out; //암시적 any를 반환하므로 오류 발생
}

any타입의 진화는 암시적 any타입에 어떤 값을 할당할 때만 발생한다. 그리고 어떤 변수가 암시적 any 상태일 때, 값을 읽으려고 하면 오류가 발생한다. 하지만, 주의해야 할 점이 있다.

function makeSquares(start: number, limit: number) {
  const out = [];
  range(start, limit).forEach(i => {
    out.push(i * i);
  });
  return out; //any[]로 판단, 오류 발생
}

여기서 숫자가 곱해진 값이 out 배열에 추가되기 때문에 반환값은 number[]로 추론될 것으로 보이나, any[] 형식으로 추론되어 반환되기 때문에 에러가 발생한다. 루프를 도는 함수를 호출하기보다는 map을 이용하여 배열을 생성하고 any 전체를 진화시키는 방법으로 생각해볼 수 있겠다.

0개의 댓글