TypeScript Error - Type 'Ticket[] | undefined' is not an array type

Viewed 1102

How do I append an item to an array of objects to a state (React) while using TS?

This is my code:

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

I keep getting this error:

Type 'Ticket[] | undefined' is not an array type.

I tried:

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

too and the error I get:

Type 'Promise<Ticket[]>' is missing the following properties from type 'Ticket[]': length, pop, push, concat, and 28 more. Type 'Ticket[] | undefined' is not an array type.

I tried writing it in all kind of variations with no luck.

Both pointing error in this line:

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

There are few problems in your code, you can fix those:

  1. Remove the optional from state and initialize it with empty array
export type AppState = {
  tickets: Ticket[] // remove the ?
  // ...
}

constructor(props) {
  super(props)
  this.state = {
    tickets: [],
    // ...
  }
}
  1. Assuming addData is array of Ticket, you need to make handleLoadMore function async to use await on this.fetchNewData to get the data returned by it:
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),
    })
}

You should destructure adddata as well.

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