|
1 | 1 | # typed-fetch
|
2 | 2 |
|
3 |
| -typed-fetch is intended to be a drop-in replacement for [openapi-typescript/openapi-fetch](https://github.com/openapi-ts/openapi-typescript) but with a much simpler TypeScript implementation that I believe results in fewer issues and enhanced readability. |
| 3 | +typed-fetch is intended to be a drop-in replacement for [openapi-fetch](https://github.com/openapi-ts/openapi-typescript) but using a simplified TypeScript implementation that I believe results in fewer issues and superior usability/readability/debuggability. |
4 | 4 |
|
5 | 5 | ## Quickstart
|
6 | 6 |
|
7 | 7 | ```bash
|
8 | 8 | # Generate TypeScript types from OpenAPI document
|
9 |
| -typed-fetch --openapi examples/petstore-openapi.yaml --output petstore-openapi.ts |
| 9 | +typed-fetch --openapi examples/petstore-openapi.yaml --output petstore-openapi.d.ts |
10 | 10 | ```
|
11 | 11 |
|
12 | 12 | ```ts
|
13 | 13 | // Use the generated library in your .ts files
|
14 |
| -import { createClient } from "./petstore-openapi"; |
| 14 | +import type { Client as PetstoreClient } from "./petstore-openapi"; // petstore-openapi.d.ts |
| 15 | +import { createClient } from "./typed-fetch"; // typed-fetch.ts file from root of this repo |
15 | 16 |
|
16 |
| -const client = createClient({ baseUrl: "https://petstore.swagger.io/v2" }); |
| 17 | +const client = createClient<PetstoreClient>({ baseUrl: "https://petstore.swagger.io/v2" }); |
17 | 18 |
|
18 | 19 | const { data, error } = await client.POST("/store/order", {
|
19 | 20 | body: {
|
@@ -43,26 +44,30 @@ Currently this utility is not being published to npm, but it's a future possibil
|
43 | 44 |
|
44 | 45 | Type-checked [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) calls using OpenAPI + TypeScript.
|
45 | 46 |
|
46 |
| -Mostly API-compatible with [openapi-fetch](https://github.com/openapi-ts/openapi-typescript). |
| 47 | +Mostly API-compatible with [openapi-fetch](https://github.com/openapi-ts/openapi-typescript). Doesn't include extra bells and whistles like middleware support since native fetch doesn't support middlewares either. |
47 | 48 |
|
48 |
| -Why create this library, if it's nearly identical to [openapi-fetch](https://github.com/openapi-ts/openapi-typescript)? It's because openapi-fetch uses a complex generics/constraints-based TypeScript implementation for type checking, which in my opinion makes it *very* difficult to understand, test, and maintain. The goal of typed-fetch, on the other hand, is to generate simple, straightforward types given an OpenAPI document so that any generalist programmer could inspect the generated TypeScript and easiy understand it -- [see for yourself, no PhD in TypeScript required](examples/petstore-openapi.ts). |
| 49 | +Why create this library, if it's nearly identical to [openapi-fetch](https://github.com/openapi-ts/openapi-typescript)? It's because openapi-fetch uses a complex generics/constraints-based TypeScript implementation for type checking, which in my opinion makes it *very* difficult to understand, test, and debug because it [requires knowledge of esoteric TypeScript behavior](https://github.com/openapi-ts/openapi-typescript/issues/1778#issuecomment-2276217668). |
49 | 50 |
|
50 |
| -TypeScript generated with this utility is composed almost entirely of type definitions which are stripped out at compile time, resulting in an extremely lightweight fetch wrapper. As a result, typed-fetch should have the same size and performance characteristics as openapi-fetch. |
| 51 | +The goal of typed-fetch, on the other hand, is to generate simple, straightforward "dumb" types given an OpenAPI document so that any generalist programmer could inspect the generated TypeScript and easily understand it -- [see for yourself, no TypeScript black belt required](examples/petstore-openapi.d.ts). Note there are 5 lines of "evil" TypeScript required to make this library play more nicely with VSCode intellisense, but they could be removed if VSCode had better intellisense for overloaded functions. |
| 52 | + |
| 53 | +Like [openapi-fetch](https://github.com/openapi-ts/openapi-typescript), TypeScript generated with this utility is composed entirely of type definitions which are stripped out at compile time, resulting in an extremely lightweight fetch wrapper. Currently weighs in at **1.4 KiB** minified (**700 bytes** if minified and compressed) which means typed-fetch should meet or exceed the size and performance characteristics of openapi-fetch. |
51 | 54 |
|
52 | 55 | Features:
|
53 |
| -- Generated TypeScript definitions are at least an order of magnitude simpler and more straightforward than openapi-fetch, which means you can easily jump to and inspect type definitions in your favorite IDE without fear |
54 |
| -- Arbitrary combinations of required and optional parameters in request bodies are correctly type-checked (broken in openapi-fetch as of July 2024) |
55 |
| -- View your OpenAPI documentation in VSCode when you hover on functions and property names |
| 56 | +- Generated TypeScript definitions are *at least* an order of magnitude simpler and more straightforward than openapi-fetch, which means you don't have to be a TypeScript ninja to contribute to or debug issues with the type checking. |
| 57 | +- Arbitrary combinations of required and optional parameters in request bodies are correctly type-checked (broken in openapi-fetch as of August 2024 - check if [this issue](https://github.com/openapi-ts/openapi-typescript/issues/1769) is still open) |
56 | 58 | - Like esbuild, typed-fetch is written in golang, so it's lightning fast
|
57 | 59 |
|
58 | 60 | Limitations:
|
59 |
| -- Only OpenAPI 3.1+ specifications officially supported (see [migration guide](https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0)), though most OpenAPI 3.0 documents will also work. |
60 |
| -- Some OpenAPI 3 features not currently implemented, especially if it's unclear how it would map to a TypeScript API. |
| 61 | +- Only OpenAPI 3.1+ specifications "officially" supported (see [migration guide](https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0)), though all OpenAPI 3.0 documents I've tested so far also work. |
| 62 | +- Some of the more obscure OpenAPI 3 features are not currently implemented (polymorphism, links, callbacks, etc), and I don't plan to implement them unless there's both a strong use case and a clean way to map them to *both* fetch *and* TypeScript. |
61 | 63 |
|
62 |
| -Missing functionality? |
| 64 | +# Missing functionality? |
63 | 65 |
|
64 |
| -Please open an issue with the following 2 things: |
| 66 | +Please open an issue with the following 3 things: |
65 | 67 | - Snippet of valid OpenAPI 3 yaml
|
66 |
| -- Expected TypeScript to be generated |
| 68 | +- Expected behavior |
| 69 | +- Actual behavior |
| 70 | + |
| 71 | +# Note to openapi-fetch maintainers |
67 | 72 |
|
68 |
| -Also, I'm open to the idea of migrating this utility/approach *into* openapi-fetch if the maintainer(s) there are on-board; I'd rather there be one great tool everyone uses than further fragment the space. |
| 73 | +Feel free to copy any approach and/or techniques you see in this repo. I personally think the approach I implemented here in go could be fairly easily replicated in openapi-typescript, and would result in a more-maintainable and more-contributor-friendly openapi-fetch implementation. I'd be happy to help if you're interested which would obsolete this repo. |
0 commit comments