Доступ к свойствам из массива объектов внутри цикла в Typescript

#javascript #typescript #types

#javascript #typescript #типы

Вопрос:

У меня есть массив с комбинацией строк и объектов. Затем я попытался отобразить свойства массива на основе ключа в цикле. Возможно ли это сделать в typescript?

Это пример кода:

 const arr = [
  { name: 'John' },
  'Amber',
  { name: 'Cathrine' },
  'Louis',
  { name: 'Mike' }
]

arr.forEach((item, key) => {
  if (typeof item !== 'string') {
    console.log(item.name) // Works
    console.log(arr[key].name) // Doesn't work, losing type
  }
} 

Пожалуйста, проверьте эту ссылку, чтобы запустить код:
https://www.typescriptlang.org/play ?#code/MYewdgzgLgBAhgJwTAvDA2gKBjA3jMOAWwFMAuGAcgCkQALMSmAXwBpsqBBIgIxIUrsc QqQqUAwnCh0EASzAkmbDpQAyIAK5yIgjiOLkqAWTkBrJS0wBdTJkQIAdADMQCAKJxgdABQ 5UCRErDAWAJ4AlKgAfHgccs4wPlBhAA4kIIkBQTAAhCholNDyYADmlFG4HDigkCAANiSO9SCl-oFEjqIkUQD0vTAA6m5mENUwtRANTS1tDujh1l2GfQMAIiAkEIywAO4jIS0gEAqlMCnpHMyYzEA

Я действительно ценю вашу помощь, спасибо!

Комментарии:

1. Совсем не ясно, в чем проблема. Если вы исправите фрагмент кода так, чтобы он был доступен для выполнения и не содержал синтаксической ошибки, обе консоли. журналы печатают то же самое. Также неясно, что означает «потеря типа».

2. Привет, спасибо за ваш ответ, пожалуйста, проверьте эту ссылку, чтобы запустить код. typescriptlang.org/play ? #code / …

3. Как вы можете видеть, я теряю тип при попытке получить доступ к свойству ‘name’ из массива. Мне нужно, чтобы он получал доступ непосредственно из массива, а не из цикла.

4. Не уверен, зачем вам когда-либо нужно было это делать, но в этом случае либо const myItem = arr[key]; if(typeof myItem !== 'string') { console.log(myItem.name); } или console.log((arr[key] as {name: string}).name)

5. почему бы просто не использовать item.name ?

Ответ №1:

Вот как работают средства защиты типов в TypeScript. Они фильтруют только тип переменной, которая проверяется. В вашем случае вы проверяете item (in typeof item !== 'string' ) и, следовательно, item предполагается, что это не строка.

Исправить

Если вы хотите получить доступ arr[key].name , сохраните это в переменной, введите check эту переменную с помощью type guard, и тогда все готово.

Полный исправленный пример:

 const arr = [
  { name: 'John' },
  'Amber',
  { name: 'Cathrine' },
  'Louis',
  { name: 'Mike' }
]

arr.forEach((item, key) => {
  const member = arr[key];
  if (typeof  member !== 'string') {
    console.log(member.name) // Okay
  }
});
 

Комментарии:

1. let menuItem = menu[key] as typeof item В настоящее время я использую утверждения типа, предложенные @Guy Incognito в комментариях выше, но я думаю, что ваш код — лучшее решение. Что вы думаете?

2. На самом деле, я пробовал ваш код раньше, но с другим синтаксисом вместо сохранения arr[key] в новую переменную. Я напрямую проверил arr[key] оператор if, но он не сработал. Есть ли объяснение, почему это не работает?

3. if (typeof arr[key] !== 'string') { console.log(arr[key].name) } Мой предыдущий код был таким. Кстати, я действительно благодарю вас за ваш ответ, это очень помогает.