openapi-typescript

repository·main·Indexed 27 days ago

https://github.com/openapi-ts/openapi-typescript

A suite of tools to bridge the gap between OpenAPI schemas and TypeScript. It provides a CLI and Node API to generate runtime-free, statically-analyzable TypeScript types from JSON or YAML schemas, and includes openapi-fetch for type-safe network requests. The tool supports flexible schema sourcing from local files or remote servers and preserves schema fidelity without requiring a Java or Python runtime.

Tokens
36.2K
Snippets
87
Records
193
Agent score
93%

What's inside openapi-typescript

  1. Overview of openapi-typescript ecosystem

    main

    The openapi-typescript project is a suite of tools designed to provide end-to-end type safety for APIs defined by OpenAPI schemas. The ecosystem consists of three primary packages:

    • openapi-typescript: A type generator that converts OpenAPI schemas into statically-analyzable, runtime-free TypeScript types. It supports complex schemas, preserves original capitalization, and runs in any Node.js environment using either local files or remote URLs.
    • openapi-fetch: A lightweight, performant wrapper around the native Fetch API. It provides strict type inference from OpenAPI schemas with minimal generic boilerplate and reduces common tasks like await res.json().
    • openapi-react-query: A wrapper for @tanstack/react-query that provides strict type inference from OpenAPI schemas while reducing boilerplate and respecting the original TanStack APIs.
  2. Understand the Project North Star

    main
    The primary goal of openapi-typescript is to generate valid TypeScript for any OpenAPI schema. The project aims to express any valid OpenAPI document as type-safe TypeScript definition files. While historically focused on 'zero runtime', the current philosophy is that all runtime costs are justified if they are necessary and no alternatives exist.
  3. Understand the core goals of openapi-typescript

    main

    openapi-typescript is designed to convert any valid OpenAPI schema into TypeScript types with the following characteristics:

    • Statically-analyzable and runtime-free: The generated types are pure TypeScript and do not add weight to your client-side bundles (with minor exceptions like enums).
    • Schema Fidelity: Generated types match your original schema as closely as possible, preserving original capitalization and structures.
    • Environment Agnostic: The type generator only requires Node.js to run and does not depend on Java or Python.
    • Flexible Schema Sourcing: Supports fetching OpenAPI schemas from local files, local servers, or remote servers.
    • No Schema Validation: The tool focuses on type generation rather than validating the schema itself (it is recommended to use tools like Redocly for linting/validation).
  4. Improve type safety with noUncheckedIndexedAccess

    main
    Enable compilerOptions.noUncheckedIndexedAccess in your tsconfig.json. This ensures that any additionalProperties (dictionaries) are typed as T | undefined instead of just T. This prevents null reference errors when accessing arbitrary keys that might be missing or misspelled.
  5. Setup openapi-react-query client

    main

    To use $api.useQuery, you must first initialize a fetch client using openapi-fetch and then wrap it with createClient from openapi-react-query using your generated OpenAPI types.

    import createFetchClient from "openapi-fetch";
    import createClient from "openapi-react-query";
    import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
    
    const fetchClient = createFetchClient<paths>({
      baseUrl: "https://myapi.dev/v1/",
    });
    
    export const $api = createClient(fetchClient);
  6. Best practice: Embrace `snake_case` from APIs

    main

    When working with OpenAPI-derived types, avoid the urge to rename snake_case properties to camelCase to match TypeScript conventions. Preserving the API schema as-written prevents several maintenance issues:

    • Avoids manual re-typing of generated types.
    • Eliminates the need for runtime renaming, which improves performance.
    • Removes the need to build and maintain name transformation utilities.
    • Ensures requestBody objects remain compatible with the API without manual transformation.
  7. Migrate CLI flags and Node.js options (v7.0.0+)

    main

    Several options were removed from the CLI and Node.js API in version 7.0.0. To migrate, use a redocly.yaml configuration file.

    • Removed options: --auth, --httpHeaders, --httpMethod, and fetch (Node.js-only).
      • Migration: Specify these in your redocly.yaml under the http setting.
    • Renamed flags:
      • --immutable-types $\rightarrow$ --immutable
      • --support-array-length $\rightarrow$ --array-length
    • Schema Globbing: Globbing schemas is no longer supported. Use redocly.yaml to specify multiple schemas with their respective outputs.
  8. Mock requests in openapi-fetch using a spy function

    main

    To test that openapi-fetch is making the correct requests, you can provide a spy function (like vi.fn() from Vitest or jest.fn() from Jest) to the fetch option in the createClient configuration. This allows you to inspect the URL, method, and body of the outgoing request.

    import createClient from "openapi-fetch";
    import { expect, test, vi } from "vitest";
    import type { paths } from "./my-openapi-3-schema"; // generated by openapi-typescript
    
    test("my request", async () => {
      const mockFetch = vi.fn();
      const client = createClient<paths>({
        baseUrl: "https://my-site.com/api/v1/",
        fetch: mockFetch,
      });
    
      const reqBody = { name: "test" };
      await client.PUT("/tag", { body: reqBody });
    
      const req = mockFetch.mock.calls[0][0];
      expect(req.url).toBe("/tag");
      expect(await req.json()).toEqual(reqBody);
    });