TypeScript

[TypeScript]Any 타입을 대체하는 방법

DevStory 2021. 12. 21.

TypeScript에서 변수 또는 객체의 타입을 선택하기 어려운 경우 가장 편리한 방법은 any 타입을 사용하는 것입니다. any 타입을 사용하는 것은 경우에 따라 올바른 선택일 수도 있지만, any 타입을 사용하지 않고 더 유용한 방법으로 타입을 정의할 수 있습니다.

 

이번 포스팅에서는 TypeScript에서 any 타입을 대체할 수 있는 방법들을 소개합니다.

 


Union Type

TypeScript에서 함수의 매개변수를 any 타입으로 정의할 수 있습니다.

 

예를 들어 금액을 매개변수로 받아서 1원 단위를 절사 하는 함수를 작성한다고 가정합니다. 함수로 전달되는 금액은 일반적으로 number 타입이겠지만, string 타입으로 전달될 수 있습니다.

 

금액은 string, number 타입 이외의 타입으로 정의될 수 있으므로 다음은 매개변수를 any 타입으로 정의한 예제입니다.

function getMoney(money: any): number {
  let returnMoney = 0;

  if(typeof money === "string") {
    // 숫자로 변환 후 1원 단위 절사 로직 작성...
  }
  else if (typeof money === "number") {
    // 1원 단위 절사 로직 작성...
  }
  else {
    throw new Error("Type이 올바르지 않습니다.");
  }

  return returnMoney;
}

위 예제처럼 코드를 작성하면 타입이 안전하지 않고 어떤 타입이든 함수에 전달될 수 있습니다.

함수 매개변수가 any 타입

그리고 매개변수가 any 타입이므로 InterlliSense는 어떠한 정보를 알려주지 않습니다.

 

Union 타입은 막대바( | )를 사용하여 여러 타입을 결합합니다. 다음은 함수의 매개변수를 Union 타입을 사용하여 string 타입과 number 타입으로 결합한 예제입니다.

function getMoney(money: string | number): number {
  let returnMoney = 0;

  if(typeof money === "string") {
    // 숫자로 변환 후 1원 단위 절사 로직 작성...
  }
  else if (typeof money === "number") {
    // 1원 단위 절사 로직 작성...
  }
  else {
    throw new Error("Type이 올바르지 않습니다.");
  }

  return returnMoney;
}

Union 타입을 사용하여 함수 getMoney()의 매개변수로 string 타입과 number 타입만 허용한다는 것을 명시해주며, 자동 완성 및 IntelliSense 기능으로 문제가 되는 코드를 확인할 수 있습니다.

함수 매개변수가 Union 타입


배열(Array)을 사용

함수의 매개변수를 배열로 가지며, 배열 요소의 length를 새로운 배열의 요소로 반환하는 경우를 구현해야 한다고 가정합니다. 함수의 매개변수의 배열은 어떠한 타입일지 모르므로 any 타입으로 정의하고 반환되는 배열은 number 타입으로 정의합니다.

function getArrayElementLength(array: any[]): number[] {
  return array.map(item => item.length);
}

console.log(getArrayElementLength(["A", "AB", "ABC"]));
// [1, 2, 3]

console.log(getArrayElementLength([1, 2, 3]));
// [undefined, undefined, undefined]

문제는 number 타입의 배열을 전달하면, number 타입은 length 속성이 없으므로 undefined를 반환하며, IntelliSense는 위 예제에서 문제점을 찾지 못해 어떠한 정보도 전달하지 않습니다. 만약, getArrayEmelemtnLength() 함수가 반환한 배열로 어떠한 로직을 작성하는 경우 런타임 시점에 오류가 발생할 수 있습니다.

함수 매개변수가 any 타입

 

따라서 매개변수를 any 타입이 아닌 length 속성이 존재하는 타입으로 정의해야 합니다.

function getArrayElementLength(array: {length: number}[]): number[] {
  return array.map(item => item.length);
}

console.log(getArrayElementLength(["A", "AB", "ABC"]));
// [1, 2, 3]

console.log(getArrayElementLength([1, 2, 3]));
// [undefined, undefined, undefined]

배열의 요소가 number 타입인 경우 IntelliSense에 의해 문제가 되는 코드를 미리 확인할 수 있습니다.

함수 매개변수가 {length: number} 타입


unknown Type

any 타입은 모든 타입을 허용하기 때문에 any 타입인 변수 또는 객체를 연산하면 결과가 NaN, undefined, null 값으로 나올 수 있으며, IntelliSense는 이러한 문제를 잡아주지 않습니다. 개발 시점에는 문제가 없지만, 런타임 시점에 문제가 발생할 수 있습니다.

 

개발 시점에 타입을 안전하게 처리하기 위해 any 타입이 아닌 unknown 타입을 사용합니다.

function anyFunc(val: any) {
  val();
}

function unknownFunc(val: unknown) {
  val();
}

any 타입 대신 unknown 타입을 사용하면 개발 시점에 문제가 되는 코드를 확인할 수 있습니다.

unknown 타입

반응형

댓글