How do you type hint overriding a built in axios method that returns a promise?

79 Views Asked by At

I've been trying to add a caching layer to apisauce. I followed a guide on https://techblog.geekyants.com/a-guide-to-react-native-offline-support which gave me the following code:

import {create} from 'apisauce';

import cache from '../utility/cache';

const apiClient = create({
  baseURL: 'https://randomuser.me',
});

const get = apiClient.get;

//^ altering the get()
apiClient.get = async (url, params, axiosConfig) => {
  const response = await get(url, params, axiosConfig);

  if (response.ok) {
    await cache.store(url, response.data); //* caching the response
    return response;
  }

  const data = await cache.get(url); //* retrieving the data from the cache
  return data ? {ok: true, data} : response;
};

export default apiClient;

This code works perfectly, however it throws errors which I cannot figure out how to resolve.

The specific error that I'm getting is:

src/api/client.tsx:39:1 - error TS2322: Type '<T, U = T>(url: string, params: {} | undefined, axiosConfig: AxiosRequestConfig | undefined) => Promise<ApiErrorResponse | ApiOkResponse | { ...; }>' is not assignable to type '<T, U = T>(url: string, params?: {} | undefined, axiosConfig?: AxiosRequestConfig | undefined) => Promise<ApiResponse<T, U>>'. Type 'Promise<ApiErrorResponse | ApiOkResponse | { ok: true; data: never; }>' is not assignable to type 'Promise<ApiResponse<T, U>>'. Type 'ApiErrorResponse | ApiOkResponse | { ok: true; data: never; }' is not assignable to type 'ApiResponse<T, U>'. Type 'ApiErrorResponse' is not assignable to type 'ApiResponse<T, U>'. Type 'ApiErrorResponse' is not assignable to type 'ApiErrorResponse'. Type 'unknown' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.

39 apiClient.get = async (url, params, axiosConfig) => {

I have tried to add in more type hinting and return types. However, I can't figure out how to return as the following type: ApiResponse<T, U> | PromiseLike<ApiResponse<T, U>>

const get = apiClient.get
apiClient.get = async <T, U = T>(
  url: string,
  params?: {},
  axiosConfig?: AxiosRequestConfig
): Promise<ApiResponse<T, U>> => {
  const response = await get(url, params, axiosConfig)

  if (response.ok) {
    cache.store(url, response.data)
    return new Promise((resolve, reject) => {
      resolve(ApiOkResponse<response.data>)
    })
  }

  const data = await cache.get(url)
  return new Promise((resolve, reject) => {
    if (data) {
      resolve({ ok: true, data })
    }

    reject(response)
  })
}
0

There are 0 best solutions below