openapi-to-typescript
This skill converts OpenAPI 3.0 specifications in JSON or YAML format into TypeScript interfaces and type guards. Use it when needing to generate TypeScript types from an API specification, create API interfaces from an OpenAPI schema, or automate type definitions from endpoint documentation.
git clone --depth 1 https://github.com/softaworks/agent-toolkit /tmp/openapi-to-typescript && cp -r /tmp/openapi-to-typescript/dist/plugins/openapi-to-typescript/skills/openapi-to-typescript ~/.claude/skills/openapi-to-typescriptSKILL.md
# 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:**
```typescript
// OpenAPI: type: object, properties: {id, name}, required: [id]
interface Example {
id: string; // required: no ?
name?: string; // optional: with ?
}
```
**Array:**
```typescript
// OpenAPI: type: array, items: {type: string}
type Names = string[];
```
**Enum:**
```typescript
// OpenAPI: type: string, enum: [active, draft]
type Status = "active" | "draft";
```
**oneOf (Union):**
```typescript
// OpenAPI: oneOf: [{$ref: Cat}, {$ref: Dog}]
type Pet = Cat | Dog;
```
**allOf (Intersection/Extends):**
```typescript
// OpenAPI: allOf: [{$ref: Base}, {type: object, properties: ...}]
interface Extended extends Base {
extraField: string;
}
```
## Code Generation
### File Header
```typescript
/**
* 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`:
```typescript
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`:
```typescript
// 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:
```typescript
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)
```typescript
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)
```typescript
// OpenAPI: items: {$ref: "#/components/schemas/Product"}
// TypeScript:
items: Product[] // reference, not inline
```
## Complete Example
**Input (OpenAPI):**
```json
{
"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):**
```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 interfAdd a skill to the project with validation and README generation
Sync root README.md with current skills inventory from skills/ directory
Use this agent when you need to visualize UI concepts through ASCII mockups before implementation. Examples: <example>Context: User has an idea for a dashboard layout with data tables and charts. user: 'I want to create a dashboard that shows user analytics with a sidebar navigation, main content area with charts, and a data table below' assistant: 'I'll use the ascii-ui-mockup-generator agent to create multiple ASCII mockup variations for your dashboard concept.' <commentary>The user wants to visualize a UI concept, so use the ascii-ui-mockup-generator to create multiple ASCII representations they can choose from.</commentary></example> <example>Context: User is designing a form layout with multiple input fields. user: 'I need a contact form with name, email, message fields and a submit button' assistant: 'Let me use the ascii-ui-mockup-generator to create several ASCII mockup options for your contact form layout.' <commentary>Since the user needs to visualize form layouts, use the ascii-ui-mockup-generator to provide multiple ASCII design options.</commentary></example>
codebase-pattern-finder is a useful subagent_type for finding similar implementations, usage examples, or existing patterns that can be modeled after. It will give you concrete code examples based on what you're looking for! It's sorta like codebase-locator, but it will not only tell you the location of files, it will also give you code details!
PROACTIVELY use when reviewing communication drafts or preparing difficult conversations. Provides email refinement, tone calibration, roleplay practice, and presentation feedback with actionable suggestions.
Default agent for handling complex, multi-step tasks with automatic delegation capabilities
Mermaid diagram specialist for creating flowcharts, sequence diagrams, ERDs,
Expert UI/UX design critic and advisor who provides research-backed, opinionated feedback on interfaces. Use when you need honest assessment of design decisions, want to avoid generic "AI slop" aesthetics, need evidence-based UX guidance, or want distinctive design direction grounded in actual user behavior research. This agent will push back on bad ideas and cite sources for every recommendation.