Error TS2342: The index expression argument must be of type "string", "number", or "any"

I have some places in my code that look like this:

var array = [];
MyClass myObject = new MyClass();
array[myObject] = "something";

      

I mostly use objects as keys in my array. I didn't think much about it as it feels natural, the code compiles fine and I didn't find any errors because of this.

I did code today by clicking on an unrelated section of code and Travis was complaining:

error TS2342: An index expression argument must be of type 'string', 'number', or 'any'.

      

on the line array[myObject] = "something";

I believe this is due to a recent update tsc

. Anyway, it brings this issue to my attention and now I'm not sure what I'm doing right:

  • What happens when you use objects as array keys? Are they converted to string? If so, what is the string made from the object that must be unique (like the hash value of the object)?
  • In short, am I doing it wrong? If so, what should I do to fix this problem?
+3


source to share


3 answers


I mostly use objects as keys in my array.

Bad idea. JavaScript does not support objects as keys. It calls toString

for objects to get a string representation before indexing.



Fix: Use a function makeString

. Checkout: https://github.com/basarat/typescript-collections#a-sample-on-dictionary for example

+6


source


All keys (all keys) of objects in JavaScript are strings. The default behavior of objects in JavaScript when converted to string is "object object". I'm a little surprised that you haven't hit it with an error yet, since it's entirely about using objects as keys:



class MyClass { }
var array = [];
var myObject1 = new MyClass();
var myObject2 = new MyClass();
array[myObject1] = "something";
array[myObject2] = "something else";
// Prints "[object Object]"
console.log(Object.keys(array).join(','));
// Prints "something else", not "something"
console.log(array[myObject1]);

      

+3


source


For the reasons given in the accepted answer, there is little use of class instances as the key object. However, if you DO have to make it work, here's how you do it.

class MyClass { }
var array = [];
const myObject = new MyClass();
array[<string> myObject] = "something";

      

Notice how I defined <string>

before myObject. It does not change the way Typescript is compiled (see below), but it does change the way Typescript is interpreted.

var MyClass = (function () {
    function MyClass() {
    }
    return MyClass;
}());
var array = [];
var myObject = new MyClass();
array[myObject] = "something";

      

0


source







All Articles