【问题标题】:TypeScript Error - Type 'Ticket[] | undefined' is not an array typeTypeScript 错误 - 类型 'Ticket[] | undefined' 不是数组类型
【发布时间】:2021-06-04 21:13:03
【问题描述】:

如何在使用 TS 时将项目附加到对象数组的状态(React)?

这是我的代码:

export type AppState = {
    tickets?: Ticket[],
}

export type Ticket = {
    id: string,
    title: string;
}

export type ApiC = {
    getTickets: (order:string, page:number) => Promise<Ticket[]>;
}

export class App extends React.PureComponent<{}, AppState> {

    state: AppState = {
    }


   fetchNewData = async () => {
        return await api.getTickets(this.state.currentOrder, this.state.page)
   }

    handleLoadMore = () => {

       let addData:Promise<Ticket[]> = this.fetchNewData()

        if (addData) 
            this.setState({
                tickets: [...this.state.tickets, addData]
            })
    }

我不断收到此错误:

键入'票[] | undefined' 不是数组类型。

我试过了:

let addData:Ticket[] = this.fetchNewData()

还有我得到的错误:

类型“Promise”缺少类型中的以下属性 'Ticket[]':长度、pop、push、concat 等 28 个。输入'票[] | undefined' 不是数组类型。

我尝试用各种变体写它,但没有运气。

此行均指向错误

  > 144 |               tickets: [...this.state.tickets, addData]
        |                            ^

【问题讨论】:

  • 如果this.state.tickets 未定义,你想发生什么?编译器告诉你正确的事情:现在,你的代码在这种情况下不起作用。
  • hmmm 如果它未定义 - 所以我想用 api 请求获取的新数据填充它.. 我猜。我应该在流程的哪一部分以及如何做到这一点? @jonrsharpe
  • 好吧,你目前在哪里依赖它作为一个数组?你需要确保它 is 到那时,或者处理它不是。它应该ever真的是未定义的吗?您还需要正确处理您的承诺;正如编译器告诉你的那样,你不能单方面决定一个函数返回一个值的承诺,而是返回值本身。
  • if (this.state.tickets) {...} ?我不确定我是否理解你所说的关于承诺的事情@jonrsharpe

标签: javascript reactjs typescript react-state react-typescript


【解决方案1】:

你也应该解构adddata

tickets: [...this.state.tickets, ...addData]

【讨论】:

  • 如何解构?
  • 请参考我的sn-p - tickets: [...this.state.tickets, ...addData]
  • Type 'Promise&lt;Ticket[]&gt;' is missing the following properties from type 'Ticket[]': length, pop, push, concat, and 28 more. Type 'Ticket[] | undefined' is not an array type.
  • 这并不能解决 OP 询问的问题(但可能确实解决了他们在修复此问题后会遇到的问题之一)。
  • 嗨@jonrsharpe 那么答案是什么?
【解决方案2】:

您的代码中存在一些问题,您可以解决这些问题:

  1. 从状态中移除可选项并用空数组初始化
export type AppState = {
  tickets: Ticket[] // remove the ?
  // ...
}

constructor(props) {
  super(props)
  this.state = {
    tickets: [],
    // ...
  }
}
  1. 假设addDataTicket的数组,你需要使handleLoadMore函数asyncawait上使用await来获取它返回的数据:
handleLoadMore = async () => {
  let addData = await this.fetchNewData()

  if (addData)
    this.setState({
      tickets: [...this.state.tickets, ...addData],
    })
    // Or
    this.setState({
      tickets: this.state.tickets.concat(addData),
    })
}

【讨论】:

  • 添加异步等待有效,为什么我需要在这里? (感谢您的回答)
  • 我认为 api.getTickets 使用 axios 并返回 Promise,因此您可以从那里删除 async/await。我的意思是,你可以从fetchNewData 中删除async - await。尝试阅读stackoverflow.com/q/49938266/2873538
猜你喜欢
  • 1970-01-01
  • 2018-08-19
  • 2020-06-16
  • 2021-09-11
  • 2016-02-22
  • 2023-01-20
  • 2021-12-30
  • 1970-01-01
  • 2021-05-26
相关资源
最近更新 更多