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
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.