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와 같은 메서드 타입 호환 가능
'Typescript' 카테고리의 다른 글
[TypeScript] 이펙티브 타입스크립트 정리 - 아이템 17 ~ 19 (0) | 2025.06.15 |
---|---|
[TypeScript] 이펙티브 타입스크립트 정리 - 아이템 14 ~ 16 (0) | 2025.06.14 |
[TypeScript] 이펙티브 타입스크립트 정리 - 아이템 9 ~ 13 (0) | 2025.06.08 |
[TypeScript] 이펙티브 타입스크립트 정리 - 아이템 6 ~ 8 (0) | 2025.06.03 |
[TypeScript] 이펙티브 타입스크립트 정리 - 아이템 1 ~ 5 (0) | 2025.06.01 |