본문 바로가기
Typescript

[Typescript] Array.isArray에 대한 고찰

by 맨날개발 2025. 2. 20.

Array.isArray 함수는 값이 배열인지 아닌지 판별하기 위해서 자주 사용된다. 요새는 타입스크립트로 코드를 많이 작성하는데, 이전까지는 전혀 문제가 없었으나 어느날 Array.isArray를 사용후 변수에 any[] 타입이 추가되는 문제가 발생하였다.

 

아래와 유사한 코드인데 if문을 통과한 후 list의 타입추론에 any[]가 추가되었다.

const list: (string | TypeA)[] = [];

if (Array.isArray(list)) {
  list.map((value) => {
    // ...
  });
}
const list: any[] | (string | TypeA)[]

 

그래서 그전까지는 별생각이 없이 사용했었던 isArray함수의 타입을 처음으로 찾아보게 되었다.

function isArray(arg: any): arg is any[];

 

타입정의된 것을 보고 any[]를 반환하기 때문이라는 결론을 내렸다.

 

 

그래서 새로알게 된 내용을 정리하기 위해 샘플 예제를 만들기 시작하였다. 아래와 같인 샘플 예제를 작성하고 타입을 확인해보니 완전히 다른 결과가 나왔다.

const list: string[] = ['a', 'b'];

if (Array.isArray(list)) {
  list.map((value) => {

  });
}
const list: string[]

 

그래서 문제를 다시 확인하기 위해 이전에 문제가 발생했던 경우랑 최대한 타입을 유사하게 작성 후 테스트해보았다.

type TypeA = Record<string, any>;

const list: TypeA | string[] = [];

if (Array.isArray(list)) {
  list.map((value) => {

  });
}
const list: any[] | string[];

 

TypeA에서 처럼 Record의 value 타입에 any를 사용했을 때 문제가 발생하였다.

 

대략 유추해보기로 배열도 하나의 객체이고 인덱스도 또한 문자열로 변환될 수 있는 것이니 Record로 정의된 것도 배열 타입과 호환이 되는 건가까지 생각이 흐르게 되어 다음과 같이 테스트를 해보았다.

type TypeA = Record<string, symbol>;

const list: TypeA | string[] = [];

if (Array.isArray(list)) {
  list.map((value) => {

  });
}
const list: string[];

 

하지만 결과는 string[]이 나왔다. value의 타입이 any이고 동일한 방식으로 any를 symbol로만 변경했으니 symbol[]가 나와야 하는 게 아닌가 생각이 들었다.

 

구글, 타입스크립트 검색을 해보았으나 관련된 내용을 확인할 수 없어 GPT의 도움을 받아보기로 했다. GPT와의 언쟁을 통해 나름 이해가 가는 대답을 찾을 수 있었다.

 

위에서 언급했듯이 배열의 인덱스는 문자열 인덱스로 변환이 될 수 있다고 가정한다. 배열 타입의 조건을 만족시키기 위해서는 value의 값만 일치해서는 동일한 타입이라고 볼 수 없다. 배열에는 length, pop, push 등 배열의 속성 및 메서드가 정의되어 있다.

 

그래서 Record<string, any>타입에서 any는 모든 값을 다 받을 수 있으니 length, pop, push까지 포함할 수 있다.

 

하지만 Record<string, symbol>에서는 symbol인 값만 가질 수 있기 때문에 length 등의 symbol이 아닌 값을 가질 수 없어 symbol[]이라고 할 수 없다.

 

💢 정리

정리하자면 Record<string, any>는 배열의 조건을 모두 만족하기 때문에 any[]와 호환이 된다고 할 수 있다.

  • 배열의 아이템(값) 타입이 호환 가능
  • 배열이 가지는 length 등의 속성 타입 호환 가능
  • 배열이 가지는 pop, push와 같은 메서드 타입 호환 가능