unjs / ofetch

😱 A better fetch API. Works on node, browser and workers.
MIT License
3.71k stars 121 forks source link

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

Open ysemennikov opened 1 month ago

ysemennikov commented 1 month ago

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

TimGuendel commented 3 weeks ago

+1 This would be really nice

martin-juul commented 1 week ago

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.

ysemennikov commented 1 week ago

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.