ofetch icon indicating copy to clipboard operation
ofetch copied to clipboard

Add support of TS type annotations on `ofetch.create`

Open ysemennikov opened this issue 1 year ago • 4 comments

Describe the feature

Hi everyone!

I really love using ofetch because it's very powerful and covers almost all use cases.

The one feature that is missing for me is type annotatations. I believe this could be automated using tools like openapi-typescript, which can generate TS-types based on OpenAPI specification.

So what I mean is:

// import types auto-generated from the OpenAPI spec
// they're generated by openapi-typescript
import type { paths } from './autogenerated-types/my-api';

const myApiFetch = ofetch.create<paths>(options)  // provide paths as generic to ofetch.create

// intellisense for request URL, method, body, etc.
myApiFetch('/endpoint', {
  method: 'POST',
  body: {}
})

The openapi-typescript has its own package called openapi-fetch with support of this feature, but since ofetch is great integrated into Nuxt 3, it would be very nice to also have this possibility here. And ofetch has more features than the openapi-fetch.

Additional information

  • [X] Would you be willing to help implement this feature?

ysemennikov avatar Jun 19 '24 11:06 ysemennikov

+1 This would be really nice

TimGuendel avatar Jul 03 '24 08:07 TimGuendel

The typing issue doesn't seem to appear if you use the library like this:

export function createLibrary(data: CreateLibraryRequest) {
  return apiFetch<Library>(route('api.library.create'), {
    method: 'POST',
    body: data,
  })
}

I ran into the same issue like you, but if i adjust my request all seems to be good.

martin-juul avatar Jul 11 '24 18:07 martin-juul

The typing issue doesn't seem to appear if you use the library like this:

export function createLibrary(data: CreateLibraryRequest) {
  return apiFetch<Library>(route('api.library.create'), {
    method: 'POST',
    body: data,
  })
}

I ran into the same issue like you, but if i adjust my request all seems to be good.

You are right, but in this case you need to manually define a return type for each request you send.

I suggest another feature - creating an ofetch instance and passing a generic type like this: const apiFetch = ofetch.create<apiTypes>().

And then all requests will be already properly typed.

ysemennikov avatar Jul 12 '24 08:07 ysemennikov

Is there currently any workaround to this?

I'm using Nuxt API Party which gives me a fetch client (based on openapi-typescript). I'm passing an openapi schema so I'm getting type-safety for paths, queries, etc.

I need custom interceptors logic so I tried passing the generated fetch client to createFetch function like below but I lose the type hints

// $typedFetch is the fetch client generated by API Party module
const customFetch = createFetch({ fetch: $typedFetch }).create({
  baseURL: 'my-api-url',
  onRequest({ options }) {
    // Custom options
  },
})

// This doesn't provide intellisense
await customFetch('endpoint-path')

// This does provide intelliSense, but can't extend it
await $typedFetch('endpoint-path')

MuhammadM1998 avatar Jan 27 '25 13:01 MuhammadM1998