【问题标题】:Can't access object property even though type of returns it is an object - React + Typescript即使返回的类型是对象,也无法访问对象属性-React + Typescript
【发布时间】:2021-02-05 18:32:03
【问题描述】:

我有一个 React 状态,它是一个对象数组,我正在 setState 方法中向它添加一个对象。对象添加正确。

现在当我尝试在其他函数中访问对象时,我无法访问对象的属性。我可以在控制台上看到该对象与属性一起存在。我在 stackoverflow 上查看了其他与异步调用相关的类似问题,但我的不属于该范围。

我已经创建了这样的对象数组,

interface ResultState{
....
localArray : object[];
}

在构造函数中将其初始化为 null。

然后向它添加一个对象,例如,

localArray : this.state.localArray.concat(Items1)

我的控制台输出:

localArray -> [{}]
              0:
                 name: 'abcd'
                 roll_num: 10
                 address: [{...}]
                     0: {Street:  'abcdefgh', aptnum: 1}

现在我想访问对象的地址。 我的代码是这样的,

const resultObject = this.state.localArray[0];
return resultObject.address;

但是我得到一个错误属性地址不存在于类型对象上。

当我执行 console.log(typeof(resultObject)) 时,出现对​​象。

这可能是什么原因?

【问题讨论】:

  • JSON.stringify(this.state.localArray[0]) 的输出是什么?我不确定,但我认为某些浏览器会记录对对象的引用,因此当对象在记录后被修改时,它也会修改记录的值
  • 输出是这样的,{"name":"abcd","roll_num":10,"address":"..."}
  • 只是为了确定:这会在分配resultObject 之前被记录下来?和JSON.stringify(resultObject)的日志记录一样?
  • 是的,两者都是。我在assigng resultObject之前记录它,resultObject的stringify也是一样的。
  • 对于localArray: object[],您实际上使用的是“对象”类型吗?确保任何类型的对象都定义了地址字段。如果您没有类型,请尝试localArray: any[]

标签: reactjs typescript


【解决方案1】:

是的,这是因为数组的类型。改成localArray: any[]后,就成功了!

【讨论】:

    【解决方案2】:

    我很高兴你让它工作了,但是使用类型 any[] 不是很好,因为它表示你的数组可以包含任何东西。您真正想要的是让 typescript 知道数组中特定对象的类型。根据您发布的内容,应该是这样的:

    interface Address {
        Street: string;
        aptnum: number;
    }
    
    interface Entry {
        name: string;
        roll_num: number;
        address: Address[];
    }
    
    interface ResultState {
        ....
        localArray: Entry[];
    }
    

    这样 typescript 知道你的数组元素是对象,但它也知道哪些属性是有效的以及每个属性的类型是什么。

    【讨论】:

    • 但问题是这个对象来自 api 调用,并且 json 结构可以有多种变化。那么在这种情况下应该怎么做呢?
    • 您知道拨打电话时会得到哪些变化吗?如果是这样,您将使用泛型在调用时定义类型。如果您在看到响应之前不知道响应是什么样子,那么您将使用所谓的有区别的联合。
    • 另一种思考方式是“我现在需要这个功能的最低要求是多少?”无需输入整个响应,只需输入您正在使用的部分。您正在访问resultObject.address,因此您希望数组中的每个对象都有一个address 属性,否则这没有意义。所以你可以说localArray: {address: Address[]}[] 如果对象不仅具有该属性,那很好,但是如果您不能确定对象包含该属性,则会出现并且应该出现错误。打字稿错误的重点是避免潜在的运行时错误。
    • 是的,我的address 定义将根据某些标准而改变。将有 5 种变化。所以在这种情况下我可以使用泛型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多