項目17 数値型のインデックスシグネチャを避ける
JavaScriptのオブジェクトについて
JavaScriptのオブジェクトは文字列(またはSymbol)のキーを任意の型の値にマップしたもの
キーには文字列もしくは、Symbolを使う
JavaScriptのオブジェクトには。PythonやJavaにあるような「ハッシュ可能な」オブジェクトという概念はない
複雑なオブジェクトをキーとして使おうとするとtoStringが呼ばれ文字列化される
code:js
x = {}
x1,2,3 = 2
x // {'1,2,3': 2}
hr.icon
数値はキーとして使用できない
数値をプロパティ名として利用するとJavaScriptはランタイムで文字列に変換する
code:js
{1:2, 3:4} // {'1': 2, '3': 4}
配列も同様に文字列に変換される
文字列キーを使っても要素にアクセスできる
code:js
x = 1,2,3
x'1' // 2
TypeScriptの場合
TypeScriptでは、数値キーを許可し、文字列と区別することで、これをモデリングしている
Arrayの型宣言を見ると
code:ts
interface Array<T> {
// ...
n: number: T;
}
この仕様のお陰で、数値とみなせない値はエラーとすることができる
code:ts
const xs = 1, 2, 3;
const x0 = xs0; // OK
const x1 = xs'1'; // 数値を文字列化したものもOK
const x2 = xs'hoge' // number型の値でないためエラー
代案
数値を使ってインデックスしたい場合は、Array型やタプル型を利用するも
ただし、意図的にArrayに含まれるpushやconcatメソッドを使えないようにしたい場合は避ける
もしくはArrayLike、Iterable型を使う
code:ts
const tupleLike: ArrayLike<string> = {
'0': 'A',
'1': 'B',
length: 2,
}; // OK
まとめ
自分で定義する型にはインデックスにnumber型を使わない
インデックスにnumber型が使えるのは、TypeScriptでArray型を使いやすくするため
#TypeScript