cli-tool/components/skills/development/openapi-to-typescript/SKILL.md
Converts OpenAPI 3.0 JSON/YAML to TypeScript interfaces and type guards. This skill should be used when the user asks to generate types from OpenAPI, convert schema to TS, create API interfaces, or generate TypeScript types from an API specification.
npx skillsauth add davila7/claude-code-templates openapi-to-typescriptInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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
components/schemaspaths (request/response types)types/api.ts in current directory)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.
| OpenAPI | TypeScript |
|-------------|--------------|
| string | string |
| number | number |
| integer | number |
| boolean | boolean |
| null | null |
| Format | TypeScript |
|---------------|-------------------------|
| uuid | string (comment UUID) |
| date | string (comment date) |
| date-time | string (comment ISO) |
| email | string (comment email)|
| uri | string (comment URI) |
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;
}
/**
* Auto-generated from: {source_file}
* Generated at: {timestamp}
*
* DO NOT EDIT MANUALLY - Regenerate from OpenAPI schema
*/
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;
}
required[] have no ?required[] have ?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 responseFor 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:
typeof value === 'object' && value !== null'field' in valuetypeofArray.isArray().includes()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'
);
}
When encountering {"$ref": "#/components/schemas/Product"}:
Product)// OpenAPI: items: {$ref: "#/components/schemas/Product"}
// TypeScript:
items: Product[] // reference, not inline
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'
);
}
| 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 |
tools
No-code automation democratizes workflow building. Zapier and Make (formerly Integromat) let non-developers automate business processes without writing code. But no-code doesn't mean no-complexity - these platforms have their own patterns, pitfalls, and breaking points. This skill covers when to use which platform, how to build reliable automations, and when to graduate to code-based solutions. Key insight: Zapier optimizes for simplicity and integrations (7000+ apps), Make optimizes for power
tools
Use only when the user explicitly asks to stage, commit, push, and open a GitHub pull request in one flow using the GitHub CLI (`gh`).
tools
Workflow automation is the infrastructure that makes AI agents reliable. Without durable execution, a network hiccup during a 10-step payment flow means lost money and angry customers. With it, workflows resume exactly where they left off. This skill covers the platforms (n8n, Temporal, Inngest) and patterns (sequential, parallel, orchestrator-worker) that turn brittle scripts into production-grade automation. Key insight: The platforms make different tradeoffs. n8n optimizes for accessibility
development
Trigger.dev expert for background jobs, AI workflows, and reliable async execution with excellent developer experience and TypeScript-first design. Use when: trigger.dev, trigger dev, background task, ai background job, long running task.