아이템16
number 인덱스 시그니처보다는 Array,튜플,ArrayLike를 사용하기
-
자바스크립트의 객체는 키, 값 쌍의 모음입니다. 키는 보통 문자열이고, 값은 어떤 것이든 될 수 있습니다. 속성 이름으로 숫자를 사용하려고하면 자바스크립트 런타임은 문자열로 변환합니다
-
문자열을 사용해도 배열에 접근할 수 있고, 배열의 Key 를 나열하면 키가 문자열로 출력됩니다.
x = []; // 배열 선언
x = [1, 2, 3]; // 배열 할당
x[0]; // 호출 : 1
x["1"]; // 호출 : 2
Object.keys(x); // ['0','1','2']
- 타입스크립트는 숫자 키를 허용하고, 문자열 키와 다르게 인식한다.
- 당연히 코드는 실제 동작하는게 아닌 런타임에서 제거된다.
interface Array<T> {
[n: number]: T;
}
- Object.keys 는 여전히 문자열로 반환합니다. 마지막 줄에서는 string 이 number 에 할당되고 있으나 코드는 잘 동작합니다.
const xs = [1, 2, 3];
const keys = Object.keys(xs); //타입 : string[]
for (const key in xs) {
// for-in
key; // '1' 타입 : string
const x = xs[key]; //xs[1] : 2
}
//인덱스 타입이 중요하지 않다면 for-of
for (const x of xs) {
x;
}
//인덱스의 타입이 중요하다면 forEach
xs.forEach((x, i) => {
i; // 현재 요소의 인덱스 : number
x; // x로 할당됨 : number
});
//중간에 멈춰야한다면
for (let i = 0; i < xs.length; i++) {
const x = xs[i];
if (x < 0) break;
}
- 배열과 비슷한 형태의 튜플을 사용하고 싶다면 ArrayLike 타입을 사용합니다
function checkedAccess<T>(xs: ArrayLike<T>, i: number): T {
if (i < xs.length) {
return xs[i];
}
throw new Error(`배열의 끝을 지나서 ${i}를 접근하려고 했습니다`);
}
요약
-
배열은 객체이므로 키는 수자가 아니라 문자열입니다. 인덱스 시그니처로 사용된 number 타입은 버그를 잡기 위한 순수 타입스크립트 코드입니다.
-
인덱스 시그니처에 number 를 사용하기 보다 Array 나 튜플, 또는 ArrayLike 타입을 사용하는 것이 좋습니다.