Перебор объекта с интерфейсом, тип несовместимости - PullRequest
0 голосов
/ 18 марта 2020

хорошо, вот пример кода, проблема в циклах такого рода, где мы перебираем объект, у которого есть интерфейс, тип индекса / значения не совместим с ключами объекта. Я не знаю, правильно ли я понимаю, но здесь посмотрите на код, и вы поймете, что я имею в виду

interface Player {
    class: number
    class_timestamp: number
    gender: number
    virtual: boolean
}

const _player: Player = {
    class: 0,
    gender: 1,
    virtual: false,
    class_timestamp: 0
}

Object.keys(_player).forEach((value, index) => {
    const val = _player[value]
})

Ошибка: Элемент неявно имеет тип 'any', потому что выражение типа ' Строка 'не может использоваться для индексации типа' Player '. Не найдена подпись индекса с параметром типа 'string' для типа 'Player'.ts (7053)

Может кто-нибудь сказать мне, как перебирать объекты вроде этого? Нужно ли создавать пользовательские типы для индекса / значения?

1 Ответ

0 голосов
/ 18 марта 2020

Мы можем решить проблему следующим образом:

 _player[value as keyof Player]

Мы делаем здесь утверждение типа, мы гарантируем компилятору, что все здесь будет иметь значения ключей типа Player.

Но главный вопрос заключается в том, почему Object.keys не сужает тип до ключей типа Player, поскольку именно это мы и делаем. Это не из-за структурной типизации и имеет определенные правила совместимости типов . Рассмотрим следующий пример:

function test(player: Player) {
  return Object.keys(_player).forEach((value, index) => {
    const val = _player[value as keyof Player]
  })
}

// below object has more keys than Player interface
const moreThanPlayer = {
  ..._player,
  more: 'x'
}

test(moreThanPlayer); // no compilation error but there is one key more!

Как вы можете видеть, TS допускает передачу подтипа Player, и это явно означает, что Object.keys будет иметь больше членов, чем только ключи игроков. Вот почему TS не сужает эту функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...