nuxt-open-fetch icon indicating copy to clipboard operation
nuxt-open-fetch copied to clipboard

Return type of useClient is not correct with default

Open kingyue737 opened this issue 1 year ago • 3 comments

Firstly, thank you very much for this awesome module!

Expected (like built-in useFetch)

// type of data is ref<Data[] | null>
const { data } =useFetch<Data[]>(url)

// type of data is ref<Data[]>
const { data } =useFetch<Data[]>(url, {default: ()=>[] }) // return type of default need to be compatible with Data[]

Actual Behavior with nuxt-open-fetch

// type of data is ref<Data[] | never[]>
const { data } =useClient(url, {default: ()=>[] })

kingyue737 avatar Apr 26 '24 09:04 kingyue737

Hi @kingyue737, thank you!

By default data will have union type of OpenAPI response type and the type from the default. For example if you create /server/api/foo.ts handler:

export default defineEventHandler(async () => {
  return {
    bar: 'Hello',
  }
})

then you will see that the data is a union type of Nitro response and the type from the default:

// type of data is  Ref<never[] | { bar: string }>
const { data } = useFetch('/api/foo', {
  default: () => []
})

I think useFetch behaviour is incorrect :). For example, if you add transform callback, it will also complain that it's return type should be Data[]. But in this case the transform is useless, because the whole point of transform is to change the data.

const { data } = useFetch<Data[]>(url, { 
  transform: () => [],
  default: () => [] 
})

I think it makes sense to open an issue in Nuxt, because NuxtOpenFetch uses UseFetchOptions type from Nuxt and doesn't modify the logic of default/transform.

enkot avatar Apr 28 '24 23:04 enkot

On the other hand, it is controversial whether default should be the same type as the OpenAPI/Nitro response type.

enkot avatar Apr 28 '24 23:04 enkot

For example, if you add transform callback, it will also complain that it's return type should be Data[]. But in this case the transform is useless, because the whole point of transform is to change the data.

Agree. It's strange that return type of transform should be Data[].

However, in my opinion, default should be the same type as the OpenAPI/Nitro response type (or the type from the transform if it exists). Not only useFetch of Nuxt, but useAsyncState of Vueuse also forces default to be the same as response type. Aligning with Nuxt and Vueuse can ease the migration to nuxt-open-fetch.

Currrently, is it possible to wrap useClient in the user end to make it return ref<Data[] instead of ref<Data[] | never[]>? We used {default: ()=>[]} almost everywhere in our projects.

kingyue737 avatar May 08 '24 11:05 kingyue737