【问题标题】:Iterating through an object with interface, Type Incompatibility遍历具有接口的对象,类型不兼容
【发布时间】:2020-03-18 05:38:20
【问题描述】:

好的,这里是一个示例代码,问题出在这种循环中,我们迭代一个具有接口的对象,索引/值的类型与对象的键不兼容。我不知道我是否说得通,但这里看看代码你会明白我的意思

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]
})

错误:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引“玩家”类型。 在“Player”类型上找不到带有“字符串”类型参数的索引签名.ts(7053)

谁能告诉我如何遍历这样的对象?我需要为索引/值创建自定义类型吗?

【问题讨论】:

    标签: typescript loops interface


    【解决方案1】:

    我们可以通过以下方式解决问题:

     _player[value as keyof Player]
    

    我们在这里进行类型断言,我们确保编译器这里的所有内容都将具有Player 类型的键值。

    但主要问题是为什么Object.keys 不会将类型缩小到Player 类型的键,因为这正是我们所做的。不是因为结构类型,有一定的type compatibility规则。考虑以下示例:

    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 没有缩小这个功能的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      • 2014-08-31
      • 2021-10-17
      • 1970-01-01
      相关资源
      最近更新 更多