如何在 TypeScript 中迭代字符串索引数组?

How to Iterate Over String Indexed Array In TypeScript?

我已经这样定义了一个静态 属性:

private static colorsByName: { [index: string]: MyColorClass}

但是当我尝试使用此处列出的答案中的 for... of 时:TypeScript for-in statement

for(let value of MyClass.colorsByName) {
    ...
}

我得到一个错误:

Type { [index: string]: MyColorClass; } is not an array type or a string type.

如果我切换到使用 for in,错误消失,但 value 被输入为 any

for(let value of MyClass.colorsByName) {
    ...
}

在这种情况下 value 的实际类型是什么?理想情况下,我想循环遍历 colorsByName 属性 中的所有值,或者采用成对方法,或者只是为了返回 MyColorClass 类型。

for(let value of MyClass.colorsByName) {
    // value: MyColorClass
}

我有哪些选择?

它不是一个数组——它是一个具有 MyColorClass.

类型的字符串键和值的对象

您可以做的是通过获取对象键的数组然后将键映射到对象的属性,将其转换为数组:

const colors = Object.keys(MyClass.colorsByName).map(key => MyClass.colorsByName[key]);

由于您可能经常这样做,因此您可以创建一个可重复使用的函数来将属性转换为数组:

function propsToArray<T>(obj: { [index: string]: T; } | { [index: number]: T; }) {
    return Object.keys(obj).map(prop => obj[prop]);
}

然后你就这样使用它:

for (const color of propsToArray(MyClass.colorsByName)) {
    // use color here
}

旁注:您可能只想将此缓存存储在 MyClass.

的静态 属性 上

Object.values

或者,您也可以使用 Object.values():

for (const color of Object.values(MyClass.colorsByName)) {
    // use color here
}

但如果你使用它,你可能需要添加一个 polyfill

对于..在

在查看 Typescript 文档 (Typescript: Iterators and Generators) 时,我们看到 for..in 语法将迭代对象的 keys

for..in returns a list of keys on the object being iterated, whereas for..of returns a list of values of the numeric properties of the object being iterated.

我们可以利用它来索引我们的对象并获取强类型值:

// Go through each key of the indexed object:
for (const key in indexedObject)
{
   // Get the indexed item by the key:
   const indexedItem = indexedObject[key];
   // Now we have the item.

   // Use it...
}

解决方案

我们可以用它来优雅地解决问题:

// Go through each named color:
for (const colorName in colorsByName)
{
   // Get the strongly typed color with this name:
   const color = colorsByName[colorName]; // : MyColorClass
   // Now we have the the strongly typed color with this name.

   // Paint the world in a techni-colour rainbow...
}