WoJ
WoJ

Reputation: 29987

Where does this requirement for a Promise<void> come from?

I have a helper function that uses fetch to get data from an API:

const callApi = (endpoint: string, method = 'GET', body?: string): Promise<Response> => {
  // decide if url is dev or prod
  const url = getUrl()
  const headers = new Headers()
  headers.set('infinote-token', store.infinoteToken as string)
  const initObject = {
    headers: headers,
    method: method,
    body: method === 'POST' ? body : undefined
  }
  return fetch(`${url}${endpoint}`, initObject)
    .then(r => {
      if (r.ok) {
        apiIsOnline()
      } else if (r.status === 403) {
        store.needToSetToken = true
        apiIsOnline()
      } else {
        apiIsOffline()
        throw Error(r.statusText)
      }
    })
    .catch((reason) => {
      log.debug(`API call rejected because: ${reason}`)
      return Promise.reject()
    })
}

It generates a TS error:

TS2322: Type 'Promise<void | Response>' is not assignable to type 'Promise<Response>'.    
          Type 'void | Response' is not assignable to type 'Response'.
            Type 'void' is not assignable to type 'Response'.

Where does this requirement for Promise<void> come from?

My understanding is that fetch returns a Promise<Response>:

The promise resolves to the Response object representing the response to your request.

Upvotes: 0

Views: 401

Answers (1)

derpirscher
derpirscher

Reputation: 17392

Yeah, fetch returns a Promise<Response>. But you are handling this result with .then(r => ...) This r is the Response you get back from fetch. The overall result of a promise chain foo().then().then()... is the result of the last then(). But your then() handler doesn't return anything (well technically it does return a Promise<void>). Thus the overall result of your fetch(...).then(...) is a Promise<void>. If you just want to pass through the Response, add a return r to your then()

return fetch(`${url}${endpoint}`, initObject)
  .then(r => {
    if (r.ok) {
      apiIsOnline()
    } else if (r.status === 403) {
      store.needToSetToken = true
      apiIsOnline()
    } else {
      apiIsOffline()
      throw Error(r.statusText)
    }
    return r;
  })

Upvotes: 2

Related Questions