为什么数组没有字符串索引签名?



我有一个数组,我想通过添加属性将其重新用作对象。

const arr = ["Hi", "my", "name", "is"];
arr.name = "Peter";

在TypeScript中,可以使用索引签名来键入。为了涵盖数字索引和字符串索引,我使用了更通用的字符串索引签名。但是,在尝试将数组分配给接口时,TypeScript会出现错误。

interface StringArray {
[index: string]: string | number;
}
const arr: StringArray = ["Hi", "my", "name", "is"];
// Type 'string[]' is not assignable to type 'StringArray'.
// Index signature is missing in type 'string[]'.(2322)
arr.name = "Peter";

我在字符串索引签名中包含了number类型,使得arr.length也被覆盖。


我的理由如下。在JavaScript中,括号属性访问器中的数字索引被转换为字符串,即arr[0]被转换为arr["0"]。考虑到这一点,我希望字符串索引签名是数字索引签名的超集,这样它就涵盖了所有的数字索引以及字符串索引。

换言之,如果以下内容有效

interface NumbersArray {
[index: number]: number;
}
const arr: NumbersArray = [10, 20, 30];

那么这也应该起作用(它不起作用(

interface NumbersArray {
[index: string]: number;
}
const arr: NumbersArray = [10, 20, 30];
// Type 'number[]' is not assignable to type 'StringArray'.
// Index signature is missing in type 'number[]'.(2322)

甚至手册中也指出,数字索引签名的类型必须是字符串索引签名的子类型,正是因为这个原因。

从数字索引器返回的类型必须是从字符串索引器返回类型的子类型。

所以我的问题归结为以下几点。

当字符串索引是数字索引的超集时,为什么数组在TypeScript中没有字符串索引签名?

PS。我不想在数组上使用as any这样的类型断言来规避类型检查。请不要建议使用类型断言。

数组类型在设计上不能有字符串索引:

interface Array<T> {  
length: number;  
[x: number]: T;  
// Other members  
}

不要混淆索引值的类型和索引的类型。

在类型论中,索引类型是一种类型构造函数。在这种情况下,它是根据索引值的类型(numberstring(构建的。

stringnumber是不相关的类型,但数字索引的类型IndexType<number>是一个子类型由于IndexType<string>的工作方式,javascript索引:可以使用数字索引值n作为访问CCD_ 14元素的字符串索引CCD_。

如果您想要的对象是一个数组,并且具有未知数量的属性,请使用交叉点类型。

字符串对象的数组,具有字符串类型的附加属性:

type StringArrayExt = Array<string> & { [index: string]: string };
let arr = ['Hi', 'my', 'name', 'is'] as StringArrayExt;
arr.name = 'Peter';

最新更新