Back to TypeScript

openapi-to-typescript

OpenAPITypeScriptAPIType GenerationSchemaCode GenerationInterfacesType Guards
2.0k📄 MIT🕒 2026-03-05Source ↗

Install this skill

npx skills add softaworks/agent-toolkit

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

The openapi-to-typescript skill automates the translation of OpenAPI 3.0 specifications into strictly typed TypeScript interfaces and runtime type guards. By parsing JSON or YAML files, it extracts schema definitions from components and maps path-based request and response objects into clean, maintainable code. It handles complex OpenAPI patterns including enums, unions (oneOf), and intersections (allOf), ensuring that generated types accurately reflect the API contract. The tool enforces type safety by creating guard functions that validate data at runtime, verifying field existence and primitive types against the original specification. It preserves documentation by converting OpenAPI descriptions into JSDoc comments, resulting in code that is both type-safe and self-documenting for frontend or backend development teams.

When to Use This Skill

  • Synchronizing frontend types with backend API changes
  • Implementing type-safe fetch or Axios wrappers
  • Bootstrapping internal SDKs from an existing Swagger definition
  • Validating incoming API payloads against schema definitions

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • generate types from my openapi.yaml
  • create typescript interfaces from this api spec
  • convert openapi definition to ts types
  • generate type guards for my openapi file
  • sync types from api.json

Pro Tips

  • 💡Always keep your OpenAPI specification up-to-date to ensure the generated TypeScript types accurately reflect your API's current state.
  • 💡Combine this skill with a code generation skill to scaffold not just types, but also full API client boilerplate.
  • 💡Leverage the generated type guards for robust runtime validation of data received from your API endpoints, enhancing application resilience.

What this skill does

  • Converts components/schemas into exported TypeScript interfaces
  • Generates runtime type guard functions for API responses
  • Maps standard OpenAPI formats like UUID and ISO date to typed comments
  • Resolves internal references ($ref) as named types rather than inlining
  • Creates boilerplate-free request and response types for all API paths

When not to use it

  • When working with OpenAPI 2.0 (Swagger) specifications
  • When you require complex client-side code generation, such as full HTTP request methods
  • If the source OpenAPI file is fragmented across multiple external files

Example workflow

  1. Provide the path to the OpenAPI YAML or JSON file
  2. Verify the spec meets the 3.0.x structural requirements
  3. Trigger the generation process to parse schemas and paths
  4. Specify the target output directory for the generated file
  5. Review the resulting interfaces and runtime guards in types/api.ts

Prerequisites

  • An OpenAPI 3.0.x compliant specification file
  • A TypeScript-based project structure

Pitfalls & limitations

  • !Requires strict adherence to OpenAPI 3.0 format; 2.0 or 3.1 files will cause failures
  • !Runtime type guards only perform shallow validation and may not catch deeply nested object property mismatches
  • !Manual edits to the generated file are lost upon re-generation

FAQ

Does this tool generate the actual HTTP request logic?
No, it only generates the TypeScript interfaces and validation guards. You will still need to implement your own fetch or network logic.
How does it handle required fields?
It uses the required array from the OpenAPI schema. Fields listed there are standard properties, while missing fields are marked as optional using the TypeScript ? syntax.
Can I use this with Swagger 2.0 files?
No, this skill is strictly limited to OpenAPI 3.0 and will fail if provided with an older version.

How it compares

Unlike manual definition or generic prompting which often results in type drift, this skill produces deterministic, standardized code that automatically keeps validation guards in sync with the source spec.

Source & trust

2.0k stars📄 MIT🕒 Updated 2026-03-05
📄 Full skill instructions — original source: softaworks/agent-toolkit
# OpenAPI to TypeScript

Converts OpenAPI 3.0 specifications to TypeScript interfaces and type guards.

**Input:** OpenAPI file (JSON or YAML)
**Output:** TypeScript file with interfaces and type guards

## When to Use

- "generate types from openapi"
- "convert openapi to typescript"
- "create API interfaces"
- "generate types from spec"

## Workflow

1. Request the OpenAPI file path (if not provided)
2. Read and validate the file (must be OpenAPI 3.0.x)
3. Extract schemas from components/schemas
4. Extract endpoints from paths (request/response types)
5. Generate TypeScript (interfaces + type guards)
6. Ask where to save (default: types/api.ts in current directory)
7. Write the file

## OpenAPI Validation

Check before processing:

- Field "openapi" must exist and start with "3.0"
- Field "paths" must exist
- Field "components.schemas" must exist (if there are types)


If invalid, report the error and stop.

## Type Mapping

### Primitives

| OpenAPI | TypeScript |
|-------------|--------------|
| string | string |
| number | number |
| integer | number |
| boolean | boolean |
| null | null |

### Format Modifiers

| Format | TypeScript |
|---------------|-------------------------|
| uuid | string (comment UUID) |
| date | string (comment date) |
| date-time | string (comment ISO) |
| email | string (comment email)|
| uri | string (comment URI) |

### Complex Types

**Object:**
// OpenAPI: type: object, properties: {id, name}, required: [id]
interface Example {
id: string; // required: no ?
name?: string; // optional: with ?
}


**Array:**
// OpenAPI: type: array, items: {type: string}
type Names = string[];


**Enum:**
// OpenAPI: type: string, enum: [active, draft]
type Status = "active" | "draft";


**oneOf (Union):**
// OpenAPI: oneOf: [{$ref: Cat}, {$ref: Dog}]
type Pet = Cat | Dog;


**allOf (Intersection/Extends):**
// OpenAPI: allOf: [{$ref: Base}, {type: object, properties: ...}]
interface Extended extends Base {
extraField: string;
}


## Code Generation

### File Header

/**
* Auto-generated from: {source_file}
* Generated at: {timestamp}
*
* DO NOT EDIT MANUALLY - Regenerate from OpenAPI schema
*/


### Interfaces (from components/schemas)

For each schema in components/schemas:

export interface Product {
/** Product unique identifier */
id: string;

/** Product title */
title: string;

/** Product price */
price: number;

/** Created timestamp */
created_at?: string;
}


- Use OpenAPI description as JSDoc
- Fields in required[] have no ?
- Fields outside required[] have ?

### Request/Response Types (from paths)

For each endpoint in paths:

// GET /products - query params
export interface GetProductsRequest {
page?: number;
limit?: number;
}

// GET /products - response 200
export type GetProductsResponse = ProductList;

// POST /products - request body
export interface CreateProductRequest {
title: string;
price: number;
}

// POST /products - response 201
export type CreateProductResponse = Product;


Naming convention:
- {Method}{Path}Request for params/body
- {Method}{Path}Response for response

### Type Guards

For each main interface, generate a type guard:

export function isProduct(value: unknown): value is Product {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
typeof (value as any).id === 'string' &&
'title' in value &&
typeof (value as any).title === 'string' &&
'price' in value &&
typeof (value as any).price === 'number'
);
}


Type guard rules:
- Check typeof value === 'object' && value !== null
- For each required field: check 'field' in value
- For primitive fields: check typeof
- For arrays: check Array.isArray()
- For enums: check .includes()

### Error Type (always include)

export interface ApiError {
status: number;
error: string;
detail?: string;
}

export function isApiError(value: unknown): value is ApiError {
return (
typeof value === 'object' &&
value !== null &&
'status' in value &&
typeof (value as any).status === 'number' &&
'error' in value &&
typeof (value as any).error === 'string'
);
}


## $ref Resolution

When encountering {"$ref": "#/components/schemas/Product"}:
1. Extract the schema name (Product)
2. Use the type directly (don't resolve inline)

// OpenAPI: items: {$ref: "#/components/schemas/Product"}
// TypeScript:
items: Product[] // reference, not inline


## Complete Example

**Input (OpenAPI):**
{
"openapi": "3.0.0",
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"id": {"type": "string", "format": "uuid"},
"email": {"type": "string", "format": "email"},
"role": {"type": "string", "enum": ["admin", "user"]}
},
"required": ["id", "email", "role"]
}
}
},
"paths": {
"/users/{id}": {
"get": {
"parameters": [{"name": "id", "in": "path", "required": true}],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/User"}
}
}
}
}
}
}
}
}


**Output (TypeScript):**
/**
* Auto-generated from: api.openapi.json
* Generated at: 2025-01-15T10:30:00Z
*
* DO NOT EDIT MANUALLY - Regenerate from OpenAPI schema
*/

// ============================================================================
// Types
// ============================================================================

export type UserRole = "admin" | "user";

export interface User {
/** UUID */
id: string;

/** Email */
email: string;

role: UserRole;
}

// ============================================================================
// Request/Response Types
// ============================================================================

export interface GetUserByIdRequest {
id: string;
}

export type GetUserByIdResponse = User;

// ============================================================================
// Type Guards
// ============================================================================

export function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
typeof (value as any).id === 'string' &&
'email' in value &&
typeof (value as any).email === 'string' &&
'role' in value &&
['admin', 'user'].includes((value as any).role)
);
}

// ============================================================================
// Error Types
// ============================================================================

export interface ApiError {
status: number;
error: string;
detail?: string;
}

export function isApiError(value: unknown): value is ApiError {
return (
typeof value === 'object' &&
value !== null &&
'status' in value &&
typeof (value as any).status === 'number' &&
'error' in value &&
typeof (value as any).error === 'string'
);
}


## Common Errors

| Error | Action |
|-------|--------|
| OpenAPI version != 3.0.x | Report that only 3.0 is supported |
| $ref not found | List missing refs |
| Unknown type | Use unknown and warn |
| Circular reference | Use type alias with lazy reference |

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/openapi-to-typescript/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/softaworks/agent-toolkit/openapi-to-typescript/SKILL.md
  • Cursor: ~/.cursor/skills/softaworks/agent-toolkit/openapi-to-typescript/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/softaworks/agent-toolkit/openapi-to-typescript/SKILL.md

🚀 Install with CLI:
npx skills add softaworks/agent-toolkit

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid typescript issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under TypeScript and is published by Softaworks, maintained in softaworks/agent-toolkit.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.