错误 TS2342:索引表达式参数的类型必须是"字符串"、"数字"或'any'



我的代码中有一些地方看起来像这样:

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

基本上,我使用对象作为数组中的键。我没有多想,因为它感觉很自然,代码编译得很好,我没有因此遇到任何错误。

今天,我对代码的一个无关部分进行了代码推送,Travis抱怨道:

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

在线array[myObject] = "something";

我相信这是由于tsc最近的更新。不管怎样,它引起了我的注意,现在我不确定我所做的是正确的:

  • 使用对象作为数组键时会发生什么?它们会被转换成字符串吗?如果是这样,那么由对象组成的字符串是否应该是唯一的(就像对象的哈希值一样)
  • 简而言之,我做这件事的方式不对吗?如果是,我应该怎么做才能解决这个问题

基本上,我使用对象作为数组中的键。

坏主意。JavaScript不支持将对象作为键。它对对象调用toString以在索引之前获得字符串表示。

修复:使用makeString函数。签出:https://github.com/basarat/typescript-collections#a-示例的字典样本

JavaScript中对象的所有键(所有键)都是字符串。当转换为字符串时,JavaScript中对象的默认行为是生成"[object object]"。我有点惊讶你还没有遇到这样的错误,因为使用对象作为密钥是完全错误的:

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]);

由于接受答案中给出的原因,使用类实例作为对象键并不好。但是,如果您DO需要使其工作,这就是您的做法。

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

请注意,我是如何在myObject之前定义<string>的。它不会改变Typescript的编译方式(见下文),但它确实改变了Typescript对它的解释方式

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

最新更新