Description
openapi-react-query version
0.5.0
Description
The error types for all query/mutation methods, including queryOptions
, is inferred incorrectly and always results in undefined
(or null | undefined
).
The example provided in the documentation, therefor, does not work.
Copied from https://openapi-ts.dev/openapi-react-query/#basic-usage and modified only to attach it to my generated openapi schema (which was generated by openapi-typescript
).
import createFetchClient from "openapi-fetch";
import createClient from "openapi-react-query";
import type { paths } from "./api.schema.gen.js"; // generated by openapi-typescript
const fetchClient = createFetchClient<paths>({
baseUrl: "https://myapi.dev/v1/",
});
const $api = createClient(fetchClient);
const MyComponent = () => {
const { data, error, isLoading } = $api.useQuery(
"get",
"/projects/id={projectId}",
{
params: {
path: { projectId: "fake-uuid" },
},
},
);
if (isLoading || !data) return "Loading...";
if (error) return `An error occured: ${error.message}`; // !! Property 'message' does not exist on type 'never'. ts(2339)
return <div>{data.title}</div>;
};
And the editor hover-over indicates error
is null | undefined
, so the error makes sense:
The null
arrives from react-query
itself, but the undefined
is a problem, and it also appears in both the onError
callback and error
state of mutations as only undefined
.
For reference, here is the underlying path from openapi.yaml
, as generated by @nestjs/swagger
:
paths:
# ...
/projects/id={projectId}:
get:
description: Gets a project by its ID
operationId: ProjectsByIdController_get
parameters:
- name: projectId
required: true
in: path
description: The project ID
schema:
format: uuid
type: string
responses:
"200":
description: The project
content:
application/json:
schema:
$ref: "#/components/schemas/ProjectModel"
"403": &a3
description: User is not authorized to perform this action.
"404": &a4
description: The project requested could not be found.
summary: ""
tags: &a5
- projects
My thoughts as to possible sources of the error are:
The typesEdit: Never mind this, fairly confident it's the next thing.UseMutationMethod
,UseQueryMethod
, etc. get the error via the genericResponse["error"]
, butResponse
is aFetchResponse
, which is a union type, and only the first member of the union is extracted (which isundefined | never
and thenever
gets dropped by TS). Based on TypeScript 5.8.- The
ErrorResponse
andGetResponseContent
fromopenapi-typescript-helpers
expected acontent
block to be present on the error and ignores errors which do not have them.
Regardless of which of the two is correct, other errors not present in the schema can still occur, such as undocumented responses (mainly 5xx) or network errors. IMO, the error type should at least always include Error
to indicate otherwise-undocumented errors (who's to say a TypeError
or deserialization errors won't appear?), or just become unknown
as is usually the case in JS.
Edit: This following yarn patch alleviates the problem by introducing Error
as suggested and gets things working again.
openapi-fetch-npm-0.14.0-20e667e085.patch
diff --git a/dist/index.d.mts b/dist/index.d.mts
index d0bdd6b4e2ff6a89cf2014b533b37bb16abb8a44..a8e176b53ec4e32c376067d6e00a62699b10ad14 100644
--- a/dist/index.d.mts
+++ b/dist/index.d.mts
@@ -97,7 +97,7 @@ type FetchResponse<T extends Record<string | number, any>, Options, Media extend
}
| {
data?: never;
- error: ErrorResponse<ResponseObjectMap<T>, Media>;
+ error: ErrorResponse<ResponseObjectMap<T>, Media> | Error;
response: Response;
};
Reproduction
The snippets above reproduce the error when copy & pasted in under TypeScript 5.8.
Expected result
The error does not appear, as documented.
Extra
- I’m willing to open a PR (see CONTRIBUTING.md)