Как перебирать строковый индексированный массив в TypeScript?

я определил статическое свойство, как например:

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

но когда я пытаюсь использовать for... of из ответа, приведенного здесь:TypeScript for-in statement

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

я получаю сообщение об ошибке:

Type { [index: string]: MyColorClass; } не является типом массива или строкового типа.

если я переключусь на использование for in, ошибка уходит, но value введен any.

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

каков фактический тип value в этом случае? В идеале я хотел бы перебрать все значения в свойстве colorsByName, либо в парном подходе, либо просто получить MyColorClass типы вернулся.

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

какие есть варианты?

2 ответов


это не массив. Это объект со строковыми ключами и свойствами типа MyColorClass.

что вы можете сделать, это включить его в массив. Вы можете сделать это, получив массив ключей объекта, затем сопоставьте ключи со свойствами объекта:

Object.keys(MyClass.colorsByName).map(prop => MyClass.colorsByName[prop]).forEach(color =>{
    // use color here
});

поскольку вы можете сделать это много, вы можете создать многоразовую функцию, чтобы превратить свойства в массив:

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

затем вы можете использовать его с for...of:

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

или с forEach:

propsToArray(MyClass.colorsByName).forEach(color => {
    // use color here
});

Для..в

при просмотре документации по Typescript (Typescript: итераторы и генераторы), мы видим, что синтаксис for..in будет повторяться над ключи объекта.

for..in возвращает список ключей для итерируемого объекта, тогда как for..возвращает список значений числовых свойств итерируемого объекта.

мы можем использовать это в наших интересах, чтобы индексировать в наш объект и получите строго типизированное значение:

// 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...
}