Chin
Chin

Reputation: 20675

Error TS2342: An 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";

Basically I'm using objects as keys in my array. I did not think much about it since it feels natural, the code compiles fine, and I have not encountered any bugs because of this.

Today I made a code push on an unrelated section of the code and Travis complained:

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 of tsc. Anyway, it brings this problem to my attention, and now I'm not sure what I've been doing is correct:

Upvotes: 3

Views: 3056

Answers (3)

MrSimonEmms
MrSimonEmms

Reputation: 1481

For the reasons given in the accepted answer, using class instances as an object key isn't great. However, if you DO need to make it work, this is how you do it.

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

Notice how I've defined <string> before the myObject. It doesn't change how the Typescript compiles (see below), but it does change how Typescript interprets it.

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

Upvotes: 0

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 220944

All keys (all keys) of objects in JavaScript are strings. The default behavior of objects in JavaScript, when converted to a string, is to produce "[object Object]". I'm kind of surprised you haven't hit a bug with this yet, since it is entirely broken to use 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]);

Upvotes: 3

basarat
basarat

Reputation: 276269

Basically I'm using objects as keys in my array.

Bad idea. JavaScript doesn't support objects as keys. It calls toString on objects to get a string representation before indexing.

Fix : use a makeString function. Checkout : https://github.com/basarat/typescript-collections#a-sample-on-dictionary for an example

Upvotes: 6

Related Questions