openapi-ts / openapi-typescript

Generate TypeScript types from OpenAPI 3 specs
https://openapi-ts.dev
MIT License
5.58k stars 453 forks source link

Impossible 'body' field required in GET #1124

Open gtrak opened 1 year ago

gtrak commented 1 year ago

Description

I'm seeing an issue where generated typescript types result in some impossible types:

Type error: Argument of type '{ params: { path: { id: string; }; }; }' is not assignable to parameter of type 'FetchOptions<{ parameters: { path: { id: string; }; }; responses: ...snipped
  Property 'body' is missing in type '{ params: { path: { id: string; }; }; }' but required in type '{ body: never; }'.

  10 |
  11 | async function exampleGet() {
> 12 |   const { data, error } = await get(`/v1/endpoint`, {
     |                                                                             ^
  13 |     params: { path: { id: "todo" } },
  14 |   });
  15 | }

I am able to work around it by adding a field body: "" as never, which seems to be forcing TS into the right path. body: undefined or body: null does not work either.

Reproduction

I used the latest versions of openapi-fetch, openapi-typescript, and an internal OpenAPI spec with only GETs in it.

Something relevant in the generated code seems to be:

export interface components {
...
  responses: never;
  parameters: never;
  requestBodies: never;  // <--
  headers: never;
  pathItems: never;
}

Expected result

I can work out the types in this scenario more easily.

Checklist

drwpow commented 1 year ago

Edit: I didn’t know you could transfer issues!

vdawg-git commented 1 year ago

I am getting the same issue. However when I try to do something like:

{ body: '' as never }

I get a runtime error: TypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.

Not sure how to circumvent that without disabling typechecking.

kepek commented 1 year ago

Up

gtrak commented 1 year ago

body: undefined as never is able to issue requests

thibaultcapelli commented 1 year ago

Same issue here

drwpow commented 1 year ago

I think some of this may be fixed in 0.6.0 by a looser parsing of the media type.

If anyone is having issues in 0.6.0, a reproduction would be helpful with a short snippet of the OpenAPI schema you’re using 🙏

t1mmen commented 1 year ago

@drwpow I'm also having this exact issue on (every) GET requests on openapi-fetch@0.6.0 (types generated with openapi-typescript@6.2.8)

error TS2345: Argument of type '{ params: { query: { connectionId: number; }; path: { provider: string; operationId: string; }; }; }' is not assignable to parameter of type 'FetchOptions<{ parameters: { query: { connectionId: number; }; path: { provider: string; operationId: string; }; }; responses: { 200: { content: { "application/json": { message?: string; operationsLog?: { jobSummary?: { executionSeconds?: string; executeOperations?: string[]; okCount?: number; errorCount?: number; }...'.
  Property 'body' is missing in type '{ params: { query: { connectionId: number; }; path: { provider: string; operationId: string; }; }; }' but required in type '{ body: never; }'.

body: undefined as never does work. Mind you, vscode does not complain, workaround or not, but tsc does 🤷

I can't share a full spec atm, but the types generated below map to the error above. If I had to bet, this seems like a generic "applies to all GET operations"-kinda issue

export interface paths {
  "/api/1.0/integrations/{provider}/{operationId}?connectionId={connectionId}": {
    get: operations["providerOperationId"];
  };
}

// ...

export interface operations {
  providerOperationId: {
    parameters: {
      query: {
        connectionId: components["parameters"]["connectionIdParam"];
      };
      path: {
        provider: components["parameters"]["providerParam"];
        operationId: components["parameters"]["operationIdParam"];
      };
    };
    responses: {
      200: {
        content: {
          "application/json": components["schemas"]["OperationOutcome"];
        };
      };
      401: components["responses"]["Unauthorized"];
      500: components["responses"]["Error"];
    };
  };
}

(PS: Thank you for making this tool! Bug aside, what I've seen so far is awesome! 👏 )

djMax commented 1 year ago

I'm going to dig into this a bit as we are doing a big migration to openapi-typescript and a openapi-fetch-derived module that uses apollo, and I don't want to have to explain to PR reviewers why body: undefined as never is littered everywhere. Any pointers appreciated, I will report back on progress.

drwpow commented 1 year ago

I took another look into this and I am still having a little trouble recreating it myself. I do believe all of you are having issues; I’m just not sure what the root problem is. @t1mmen Thanks for publishing all that, but I wasn’t able to reproduce the problem with just that alone; I have a feeling the bug is lurking in the rest of the generated types.

I’ve published a version at npm install openapi-fetch@test. If someone could give that a try and let me know if it fixed the problem for them, that’s at least a start.

djMax commented 1 year ago

I have a hunch that it may have to do with the spec, because when I tried this on Petstore it didn't seem to have the problem.

RWOverdijk commented 1 year ago

@drwpow I tried openapi-fetch@test and it works for me (as in, no more complaints about body). I do notice that the second argument to get is required, but I have a lot of endpoints that don't require parameters. It's not a huge deal, but I wasn't sure if that's on purpose or not so I thought I'd mention it.

drwpow commented 1 year ago

I tried openapi-fetch@test and it works for me (as in, no more complaints about body)

That’s promising! That at least lets me know that’s on the right path to the root error.

I do notice that the second argument to get is required, but I have a lot of endpoints that don't require parameters.

Right—we’re tracking that with #1127. TypeScript struggled with making that 2nd param required when it truly needed to be, so currently there’s just a required object with optional keys. Issue is still tracking that. Would like to solve that before 1.0.

drwpow commented 1 year ago

v0.7.2 should improve this typing, but I believe #1280 is probably the real fix to this—it fixes the underlying typing. Hopefully once that merges & ships it will improve most peoples’ experiences.

Anyway, please give v0.7.2 a try if you didn’t try the @test version (with a caveat that the method names have been renamed to uppercase)

github-actions[bot] commented 1 month ago

This issue is stale because it has been open for 90 days with no activity. If there is no activity in the next 7 days, the issue will be closed.

vdawg-git commented 1 month ago

Is this fixed?