ProvenPin Install

openapi-typescript generate types: working versions (tested 2026-10-17)

Generate TypeScript types from an inline OpenAPI 3.1 document with the openapi-typescript programmatic API using openapiTS and astToString, asserting generated interface members and path keys offline.

passed5 passed · 0 failed2026-10-17 19:19 UTC
Status
passed
Last passed
2026-10-17 19:19 UTC
Tests
5 / 5
Language
TypeScript
Runtime
node v22.23.3
pinned versions3
openapi-typescript@7.13.0@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 39061946720

The code

Exactly the files that passed. Your agent can pull them with get_recipe("openapi-typescript-generate-types") (install), or see them on GitHub.

package.json
{
  "name": "openapi-typescript-generate-types",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "openapi-typescript": "7.13.0"
  },
  "devDependencies": {
    "@types/node": "26.6.5",
    "tsx": "4.23.15"
  }
}
src/generate.ts
import openapiTS, { astToString } from "openapi-typescript";
import type { OpenAPI3_1 } from "openapi-typescript";

export const usersSpec: OpenAPI3_1 = {
  openapi: "3.1.0",
  info: { title: "Users API", version: "1.0.0" },
  paths: {
    "/users": {
      get: {
        operationId: "listUsers",
        responses: {
          "200": {
            description: "A list of users",
            content: {
              "application/json": {
                schema: {
                  type: "array",
                  items: { $ref: "#/components/schemas/User" },
                },
              },
            },
          },
        },
      },
      post: {
        operationId: "createUser",
        requestBody: {
          required: true,
          content: {
            "application/json": {
              schema: { $ref: "#/components/schemas/NewUser" },
            },
          },
        },
        responses: {
          "201": {
            description: "Created",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/User" },
              },
            },
          },
        },
      },
    },
    "/users/{id}": {
      get: {
        operationId: "getUser",
        parameters: [
          { name: "id", in: "path", required: true, schema: { type: "string" } },
        ],
        responses: {
          "200": {
            description: "A single user",
            content: {
              "application/json": {
                schema: { $ref: "#/components/schemas/User" },
              },
            },
          },
        },
      },
    },
  },
  components: {
    schemas: {
      User: {
        type: "object",
        required: ["id", "name"],
        properties: {
          id: { type: "string" },
          name: { type: "string" },
        },
      },
      NewUser: {
        type: "object",
        required: ["name"],
        properties: {
          name: { type: "string" },
        },
      },
    },
  },
};

export async function generateTypes(
  spec: OpenAPI3_1 = usersSpec,
): Promise<string> {
  const ast = await openapiTS(spec);
  return astToString(ast);
}
test/generate.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { generateTypes } from "../src/generate.ts";

test("generates a non-empty module from an inline spec", async () => {
  const source = await generateTypes();
  assert.equal(typeof source, "string");
  assert.ok(source.length > 0);
  assert.match(source, /export interface paths/);
});

test("includes each path key", async () => {
  const source = await generateTypes();
  assert.ok(source.includes('"/users":'));
  assert.ok(source.includes('"/users/{id}":'));
});

test("includes operation members for methods and operationIds", async () => {
  const source = await generateTypes();
  assert.match(source, /export interface operations/);
  assert.ok(source.includes("listUsers:"));
  assert.ok(source.includes("createUser:"));
  assert.ok(source.includes("getUser:"));
});

test("includes component schema interface members", async () => {
  const source = await generateTypes();
  assert.match(source, /export interface components/);
  assert.match(source, /User:\s*\{/);
  assert.match(source, /NewUser:\s*\{/);
  assert.ok(source.includes("id: string"));
  assert.ok(source.includes("name: string"));
});

test("includes path parameters, request body and response content", async () => {
  const source = await generateTypes();
  assert.match(source, /path:\s*\{/);
  assert.ok(source.includes("id: string"));
  assert.ok(source.includes("requestBody"));
  assert.ok(source.includes("content"));
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.