Skip to content
This repository was archived by the owner on Nov 12, 2024. It is now read-only.

Commit 1460071

Browse files
committed
Fix types
1 parent 0043d09 commit 1460071

File tree

7 files changed

+85
-19
lines changed

7 files changed

+85
-19
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,4 @@ dist
132132
# ----
133133

134134
yarn.lock
135+
/generated/

package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,26 @@
2626
"scripts": {
2727
"prepublish": "npm run build && npm run types:check && npm run format:check",
2828
"build": "tsup",
29+
"test": "./setup-test-data.sh && tsc --project test/tsconfig.json",
2930
"types:check": "tsc --noEmit",
3031
"format": "prettier --write .",
3132
"format:check": "prettier --check ."
3233
},
34+
"dependencies": {
35+
"openapi-typescript-helpers": "0.0.7"
36+
},
3337
"devDependencies": {
3438
"@types/node": "20.11.19",
39+
"expect-type": "0.17.3",
3540
"openapi-fetch": "0.9.2",
3641
"openapi-typescript": "6.7.4",
37-
"openapi-typescript-helpers": "0.0.7",
3842
"prettier": "3.2.5",
3943
"swr": "2.2.5",
4044
"tsup": "7.2.0",
4145
"typescript": "5.2.2"
4246
},
4347
"peerDependencies": {
44-
"openapi-fetch": ">=0.9",
48+
"openapi-fetch": "0.9",
4549
"openapi-typescript": "6",
4650
"swr": "2",
4751
"typescript": "5"

pnpm-lock.yaml

+13-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

setup-test-data.sh

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
3+
./node_modules/.bin/openapi-typescript \
4+
https://petstore3.swagger.io/api/v3/openapi.json \
5+
--output ./generated/petstore.ts

src/index.ts

+27-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
import type { FetchOptions } from "openapi-fetch";
21
import type createClient from "openapi-fetch";
3-
import type { FilterKeys, PathsWithMethod } from "openapi-typescript-helpers";
2+
import type { FetchOptions, ParseAsResponse } from "openapi-fetch";
3+
import type {
4+
ErrorResponse,
5+
FilterKeys,
6+
MediaType,
7+
PathsWithMethod,
8+
ResponseObjectMap,
9+
SuccessResponse,
10+
} from "openapi-typescript-helpers";
411
import useSWR, { type SWRConfiguration } from "swr";
512

613
export function makeHookFactory<Paths extends {}>(
@@ -15,25 +22,32 @@ export function makeHookFactory<Paths extends {}>(
1522
// Define hook that is returned for consumers with typed options
1623
// based on the given path
1724
function useHook<
18-
Options extends FetchOptions<FilterKeys<Paths[Path], "get">>,
19-
Response extends Awaited<ReturnType<typeof api.GET<Path>>>
20-
>(
21-
fetchOptions: Options | null | undefined,
22-
swrConfig?: SWRConfiguration<Response["data"], Response["error"]>
23-
) {
25+
Req extends FilterKeys<Paths[Path], "get">,
26+
Options extends FetchOptions<Req>,
27+
Data extends ParseAsResponse<
28+
FilterKeys<SuccessResponse<ResponseObjectMap<Req>>, MediaType>,
29+
Options
30+
>,
31+
Error extends FilterKeys<
32+
ErrorResponse<ResponseObjectMap<Req>>,
33+
MediaType
34+
>,
35+
>(fetchOptions: Options | null, swrConfig?: SWRConfiguration<Data, Error>) {
2436
type Key = [typeof keyPrefix, Path, Options] | null;
2537

26-
return useSWR<Response["data"], Response["error"], Key>(
38+
return useSWR<Data, Error, Key>(
2739
// SWR key is based on the path and fetch options
2840
// keyPrefix keeps each API's cache separate in case there are path collisions
2941
fetchOptions ? [keyPrefix, path, fetchOptions] : null,
3042
// Fetcher function
43+
// @ts-expect-error - This functions correctly, but we don't need to fix its types
44+
// types since we rely on the generics passed to useSWR instead
3145
async ([_, url, options]) => {
32-
const { data, error } = await api.GET(url, options);
33-
if (error) {
34-
throw error;
46+
const res = await api.GET(url, options);
47+
if (res.error) {
48+
throw res.error;
3549
}
36-
return data;
50+
return res.data;
3751
},
3852
// SWR config
3953
{

test/index.spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import createClient from "openapi-fetch";
2+
import type { paths } from "../petstore";
3+
import { makeHookFactory } from "../src/index";
4+
5+
import { expectTypeOf } from "expect-type";
6+
7+
const petStoreApi = createClient<paths>({
8+
baseUrl: "https://petstore3.swagger.io/api/v3",
9+
});
10+
11+
const petStoreHook = makeHookFactory<paths>(petStoreApi, "pet-store");
12+
13+
const useOrder = petStoreHook("/store/order/{orderId}");
14+
15+
const { data } = useOrder({
16+
params: {
17+
path: { orderId: 1 },
18+
},
19+
});
20+
21+
if (data) {
22+
expectTypeOf(data).toEqualTypeOf<
23+
paths["/store/order/{orderId}"]["get"]["responses"]["200"]["content"]["application/json"]
24+
>();
25+
}

test/tsconfig.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"include": ["./src/**/*", "**/*"],
4+
"compilerOptions": {
5+
"noEmit": true
6+
},
7+
"exclude": ["node_modules"]
8+
}

0 commit comments

Comments
 (0)