Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

openapi-typesafe

/openapi-typesafe

Generuje typy TypeScript z dokumentu OpenAPI 3.x i wywołuje API przez klienta z w pełni wnioskowanymi typami.

Licencja
MIT
Ostatnia zmiana repozytorium
13.11.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
4
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
2
Przestarzałość

Brak sygnałów. Repozytorium zmienione 13.11.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Generuje typy TypeScript z dokumentu OpenAPI 3.x i wywołuje API przez klienta z w pełni wnioskowanymi typami.

Oryginalny opis (EN)

Generate TypeScript types from an OpenAPI 3.x document with openapi-typesafe and call the API through openapi-typesafe-fetch or openapi-typesafe-react-query with fully inferred types. Use when a project depends on openapi-typesafe, openapi-typesafe-fetch or openapi-typesafe-react-query; when moving a project off openapi-typescript, openapi-fetch or openapi-react-query; when openapi-typescript fails with TypeScript 7; or when writing typed API calls, middleware, auth or error handling for an OpenAPI client.

Jak działa

  1. 1. Generate the types
  2. 2. Create the client
  3. 3. Call an endpoint
  4. 4. Handle the result
  5. 5. Middleware
  6. 6. Reusable types
  7. 7. Testing code that calls the client
  8. Common mistakes
Sekcje z nagłówków SKILL.md, w oryginale · 230 linii, 1 644 słów
Podgląd SKILL.md
---
name: openapi-typesafe
description: Generate TypeScript types from an OpenAPI 3.x document with openapi-typesafe and call the API through openapi-typesafe-fetch or openapi-typesafe-react-query with fully inferred types. Use when a project depends on openapi-typesafe, openapi-typesafe-fetch or openapi-typesafe-react-query; when moving a project off openapi-typescript, openapi-fetch or openapi-react-query; when openapi-typescript fails with TypeScript 7; or when writing typed API calls, middleware, auth or error handling for an OpenAPI client.
license: MIT
---

# openapi-typesafe

openapi-typesafe turns an OpenAPI 3.0, 3.1 or 3.2 document into TypeScript types. It is a drop-in
successor to openapi-typescript 7.13 that also works with TypeScript 7. Five packages share one
version number:

| Package | Role | Replaces |
| :-- | :-- | :-- |
| `openapi-typesafe` | Generator: CLI and Node API (dev dependency) | `openapi-typescript` |
| `openapi-typesafe-fetch` | Typed `fetch` client, about 11 kB minified | `openapi-fetch` |
| `openapi-typesafe-react-query` | TanStack Query v5 hooks on top of the client, about 4 kB minified | `openapi-react-query` |
| `openapi-typesafe-helpers` | Shared utility types | `openapi-typescript-helpers` |
| `openapi-typesafe-migrate` | One-off migration command, run with `npx` | none |

Requirements: Node.js 22.12+ for the generator, Node.js 22+ (or a browser, Bun, Deno) for the
client, TypeScript 5.4 or newer (6.x and 7.x included).

Pick the task:

- New setup or typed calls: read on.
- Moving a project from openapi-typescript / openapi-fetch / openapi-react-query, or a
  TypeScript 7 error: [references/migration.md](references/migration.md).
- React components with TanStack Query: [references/react-query.md](references/react-query.md).
- Generator options, Node API, callbacks, error codes:
  [references/generator.md](references/generator.md).

## 1. Generate the types

```bash
npm i openapi-typesafe-fetch
npm i -D openapi-typesafe
npx openapi-typesafe ./openapi.yaml -o ./src/api/schema.d.ts
```

- Add a script, for example `"generate:api": "openapi-typesafe ./openapi.yaml -o ./src/api/schema.d.ts"`.
- The output exports `paths`, `components`, `operations` and `webhooks`. Never edit it by hand:
  change the OpenAPI document and regenerate.
- In CI, `openapi-typesafe ./openapi.yaml -o ./src/api/schema.d.ts --check` exits with `1` when the
  file is stale.
- Turn on `noUncheckedIndexedAccess` in `tsconfig.json`; additional properties are then typed as
  possibly `undefined`.

## 2. Create the client

```ts
import createClient from "openapi-typesafe-fetch";
import type { paths } from "./api/schema"; // generated file

export const client = createClient<paths>({ baseUrl: "https://api.example.com/v1" });
```

Create one client per base URL and reuse it. `createClient` also takes `headers` (sent with every
request), `fetch` (a custom fetch, used in tests), `querySerializer`, `bodySerializer`, `requestInitExt`
(the second `fetch` argument on Node.js, such as an undici `dispatcher`) and any `RequestInit`
field such as `credentials`.

## 3. Call an endpoint

The path string must be the literal key from the document, with its `{placeholders}`. Never build
it at run time: type inference works only on the literal.

```ts
const { data, error, response } = await client.GET("/pets/{petId}", {
  params: {
    path: { petId: 42 },
    query: { include: "owner" },
  },
});

const created = await client.POST("/pets", {
  body: { name: "Rex", tag: "dog" },
});
```

- Methods are upper-case: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`, `TRACE`,
  and `QUERY` for OpenAPI 3.2 `query` operations (it takes a `body` like `POST`). Methods under
  `additionalOperations` (3.2) are typed but not callable through the client.
- Parameters go under `params`, grouped by location: `path`, `query`, `header`, `cookie`.
  Never put a path or query value at the top level of the options.
- The request body is `body`, a plain object for JSON. The client serializes it; do not call
  `JSON.stringify` yourself.
- The client sends `Content-Type: application/json` unless you set another one; it does not read
  the media type from the document. Raw bodies (`FormData`, `Blob`, `URLSearchParams`,
  `ArrayBuffer`, typed arrays) get no default `Content-Type`; the platform sets it. For other bodies set the header in `headers`:
  - text: `body: notes, headers: { "Content-Type": "text/plain" }`; a string is then sent as is
    (with a JSON type it would be a JSON string, in quotes);
  - form: `headers: { "Content-Type": "application/x-www-form-urlencoded" }` with a plain object;
  - files (`multipart/form-data`): generate with `--binary-as-blob` (file fields become `Blob`),
    set `headers: { "Content-Type": "multipart/form-data" }` and pass the typed object as `body`;
    the client builds the `FormData` and `fetch` adds the boundary. Nested objects need a
    `bodySerializer`.
- The second argument is required only when the operation has required parameters or a required
  body.
- Do not pass generics to `GET` / `POST` and do not cast the result. Everything is inferred from
  `paths`; a cast hides the bugs the types exist to catch.
- `parseAs: "text" | "blob" | "arrayBuffer" | "stream"` changes how a success body is read
  (default `"json"`).
- Per-request `headers`, `signal`, `baseUrl` and `fetch` override the client options. Headers can
  be a record, a `Headers` object or a list of pairs; `null` removes a client header, and
  `params.header` wins over both.
- A path parameter that makes a `.` or `..` segment, or an empty first segment (`//host`), throws
  before the request.

## 4. Handle the result

Every call resolves to `{ data, error, response }`. It does not throw for HTTP errors. It rejects
when `fetch` itself fails (network error, CORS, abort), when a middleware throws, and when a
success body is not JSON (a proxy's HTML page gives a `SyntaxError`; set `parseAs: "text"` for
such a response).

| Field | Value |
| :-- | :-- |
| `data` | Parsed `2xx` body; `undefined` otherwise |
| `error` | Parsed body of any other status (`1xx`, `3xx`, `4xx`, `5xx`, `default`); `undefined` otherwise |
| `response` | The original `Response` (`status`, `headers`, `ok`) |

An error response **without a body** has `error: undefined`, and so does any `204` or `HEAD`
response. So `if (error)` alone misses an empty `500`. Check `response.ok`:

```ts
async function loadPet(petId: number) {
  const { data, error, response } = await client.GET("/pets/{petId}", {
    params: { path: { petId } },
  });
  if (!response.ok) {
    // `error` is the typed error body, or undefined when the server sent none.
    throw new ApiError(response.status, error);
  }
  return data; // the 2xx body, or undefined for an empty body (`response` does not narrow it)
}
```

- Narrow on `error` before you read `data`: `data` and `error` are a discriminated union, and
  `response` is not part of it, so `response.ok` does not narrow `data`.
- Branch on `response.status` for status-specific handling; the `error` type is the union of all
  error bodies of the operation.
- An error body is parsed only when its `Content-Type` is JSON (or missing and the body parses);
  any other error body, such as `text/plain` or HTML, comes back as text in `error`. A success
  body that is not JSON rejects (see above).
- Network failures and aborts reject: wrap the call in `try` / `catch` where you need to handle
  them, or turn them into a value with `onError` middleware (section 5).

## 5. Middleware

Middleware sees every request of a client. Register it with `client.use(...)` and remove it with
`client.eject(...)`.

```ts
import createClient, { type Middleware } from "openapi-typesafe-fetch";

const authMiddleware: Middleware = {
  async onRequest({ request }) {
    request.headers.set("Authorization", `Bearer ${await tokens.current()}`);
    return request;
  },
};

client.use(authMiddleware);
```

- `onRequest({ request, schemaPath, params, id, options })`: return a `Request` to replace it,
  return a `Response` to skip the network (cache, mock), or return nothing to leave it as is.
- `onResponse({ request, response, ... })`: return a new `Response` to replace it, or nothing.
  To read the body, read `response.clone()`: the client still has to read the original.
- `onError({ error, ... })`: called when `fetch` throws. Return nothing to rethrow, an `Error` to
  throw that error instead, or a `Response` to recover.
- `onRequest` runs in registration order; `onResponse` runs in reverse order.
- `schemaPath` is the document path such as `"/pets/{petId}"`; use it to skip middleware for some
  endpoints (for example no auth header on `/auth/login`).
- Pass `middleware: [m]` in the options of a single call to apply it to that call only.
- Throwing in `onResponse` when `!response.ok` turns HTTP errors into rejections. Do this only
  when the caller wants exceptions (for example in a TanStack Query `queryFn` that does not use
  openapi-typesafe-react-query).

## 6. Reusable types

```ts
import type { components, operations, paths } from "./api/schema";

type Pet = components["schemas"]["Pet"];
type NewPet = paths["/pets"]["post"]["requestBody"]["content"]["application/json"];
type PetResponse =
  paths["/pets/{petId}"]["get"]["responses"][200]["content"]["application/json"];
type ListPetsQuery = operations["listPets"]["parameters"]["query"];
```

From `openapi-typesafe-helpers`: `PathsWithMethod<paths, "get">` (paths that have a GET),
`SuccessResponseJSON<Op>`, `ErrorResponseJSON<Op>`, `RequestBodyJSON<Op>`.
From `openapi-typesafe-fetch`: `MethodResponse<typeof client, "get", "/pets">` (the `data` type of
a call), `ClientPathsWithMethod<typeof client, "get">`.

## 7. Testing code that calls the client

Inject the client or its `fetch`, and answer with real `Response` objects. Do not mock the client
methods.

```ts
const requests: Request[] = [];
const client = createClient<paths>({
  baseUrl: "https://api.example.com/v1",
  fetch: async (request) => {
    requests.push(request);
    return Response.json({ id: 1, name: "Rex" }, { status: 200 });
  },
});
```

The `fetch` option receives one `Request`; read `request.url`, `request.method`,
`request.headers` and `await request.json()` in assertions. Mock Service Worker (`msw`) also
works.

## Common mistakes

| Mistake | Fix |
| :-- | :-- |
| `client.GET(\`/pets/${id}\`)` | `client.GET("/pets/{petId}", { params: { path: { petId: id } } })` |
| `client.get(...)` | Methods are upper-case on the client: `client.GET(...)`; lower-case only in react-query hooks (`$api.useQuery("get", ...)`) |
| `{ query: { limit: 10 } }` at the top level | `{ params: { query: { limit: 10 } } }` |
| `body: JSON.stringify(pet)` | `body: pet` |
| `if (error) ...` as the only failure check | `if (!response.ok) ...`; `error` is `undefined` for an empty error body |
| `try { await client.GET(...) } catch` to catch a 404 | HTTP errors resolve; they do not throw. Check `response.ok` |
| `client.GET<Pet>(...)`, `data as Pet` | Remove the generic and the cast; fix the document if the type is wrong |
| Reading `data` without narrowing | Check `error` / `response.ok` first, or use `data!` only after that check |
| Editing the generated `schema.d.ts` | Change the OpenAPI document, regenerate |
| `import ... from "openapi-fetch"` / `"openapi-typescript"` | The packages are `openapi-typesafe-fetch` / `openapi-typesafe`; see the migration reference |
| `await response.json()` in `onResponse` | Read `response.clone().json()`; the client reads the original |
| A new client per request | Create the client once per base URL and reuse it |
| Installing `typescript@5` only to run the generator | Not needed: the generator has no TypeScript dependency |
Pliki w paczce (4)
  • SKILL.md 12 KB
  • references/generator.md 11 KB
  • references/migration.md 8 KB
  • references/react-query.md 6 KB

Wersje

W bazie nie ma innych skilli o nazwie openapi-typesafe.

Migawka bazy z 13.11.2026 · wersja paczki dd5b71340222 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100openapi-to-typescript
    Konwertuje specyfikacje OpenAPI 3.0 w JSON lub YAML na interfejsy TypeScript i strażników typów, aby tworzyć typy API ze schematu.
  • 100openapi-spec
    Pisze specyfikację OpenAPI 3.1, sprawdza ją Redocly CLI, generuje typy TypeScript i typowanego klienta fetch, buduje dokumentację HTML i pilnuje poprawności specyfikacji.
  • 100openapi-codegen
    Generuje typowane klienty API z OpenAPI przy użyciu openapi-typescript, openapi-generator-cli, swagger-typescript-api i trpc-openapi.
  • 100type-generation
    Generuje typy automatycznie ze schematów OpenAPI i GraphQL przez openapi-typescript i graphql-codegen oraz synchronizuje kontrakty API.
  • 100api-contract
    Projektuje kontrakt OpenAPI między backendem Spring Boot a klientami TypeScript: generuje spec, typowane klienty i sprawdza błędy RFC 9457.
  • 100rest-api-generator
    Generuje z OpenAPI serwery, klientów C# i TypeScript z hookami React Query, a także konfiguruje limity, cache, wersje i webhooki.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.