关于 openapi-to-typescript
面向开发者的技能,可将 OpenAPI 3.0 规范转换为 TypeScript 接口、请求和响应类型及类型守卫,并检查规范和处理引用。
主要功能
- 01验证 OpenAPI 3.0 规范
- 02从 Schema 生成接口
- 03生成端点请求与响应类型
- 04生成类型守卫
- 05处理 $ref 并报告错误
适用场景
- 01从 API 规范生成 TypeScript 类型
- 02创建端点请求和响应定义
- 03转换前验证 OpenAPI 文件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ softaworks/ agent-toolkit --skill openapi-to-typescript安装后在 Claude Code 中输入/openapi-to-typescript确认已加载。
附带文件README.md
详细介绍
OpenAPI 转 TypeScript
将 OpenAPI 3.0 规范转换为 TypeScript 接口和类型守卫。
输入: OpenAPI 文件(JSON 或 YAML) 输出: 包含接口和类型守卫的 TypeScript 文件
适用场景
- “根据 OpenAPI 生成类型”
- “将 OpenAPI 转换为 TypeScript”
- “创建 API 接口”
- “根据规范生成类型”
工作流
- 请求 OpenAPI 文件路径(如未提供)
- 读取并验证文件(必须为 OpenAPI 3.0.x)
- 从
components/schemas提取架构 - 从
paths提取端点(请求/响应类型) - 生成 TypeScript(接口 + 类型守卫)
- 询问保存位置(默认:当前目录下的
types/api.ts) - 写入文件
OpenAPI 验证
处理前检查:
- Field "openapi" must exist and start with "3.0"
- Field "paths" must exist
- Field "components.schemas" must exist (if there are types)
如果无效,报告错误并停止。
类型映射
基本类型
| OpenAPI | TypeScript |
|---|---|
string | string |
number | number |
integer | number |
boolean | boolean |
null | null |
格式修饰符
| 格式 | TypeScript |
|---|---|
uuid | string(注释 UUID) |
date | string(注释日期) |
date-time | string(注释 ISO) |
email | string(注释电子邮件) |
uri | string(注释 URI) |
复杂类型
对象:
// OpenAPI: type: object, properties: {id, name}, required: [id]
interface Example {
id: string; // required: no ?
name?: string; // optional: with ?
}
数组:
// OpenAPI: type: array, items: {type: string}
type Names = string[];
枚举:
// OpenAPI: type: string, enum: [active, draft]
type Status = "active" | "draft";
oneOf(联合类型):
// OpenAPI: oneOf: [{$ref: Cat}, {$ref: Dog}]
type Pet = Cat | Dog;
allOf(交叉类型/继承):
// 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
*/
接口(来自 components/schemas)
对于 components/schemas 中的每个架构:
export interface Product {
/** Product unique identifier */
id: string;
/** Product title */
title: string;
/** Product price */
price: number;
/** Created timestamp */
created_at?: string;
}
- 将 OpenAPI 描述用作 JSDoc
required[]中的字段不加?- 不在
required[]中的字段加?
请求/响应类型(来自 paths)
对于 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;
命名约定:
- 参数/请求体使用
{Method}{Path}Request - 响应使用
{Method}{Path}Response
类型守卫
为每个主要接口生成类型守卫:
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'
);
}
类型守卫规则:
- 检查
typeof value === 'object' && value !== null - 对每个必需字段:检查
'field' in value - 对基本类型字段:检查
typeof - 对数组:检查
Array.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'
);
}
$ref 解析
遇到 {"$ref": "#/components/schemas/Product"} 时:
- 提取架构名称(
Product) - 直接使用该类型(不要内联解析)
// OpenAPI: items: {$ref: "#/components/schemas/Product"}
// TypeScript:
items: Product[] // reference, not inline
完整示例
输入(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"}
}
}
}
}
}
}
}
}
输出(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'
);
}
常见错误
| 错误 | 处理方式 |
|---|---|
| OpenAPI 版本 != 3.0.x | 报告仅支持 3.0 |
| 未找到 $ref | 列出缺失的引用 |
| 未知类型 | 使用 unknown 并发出警告 |
| 循环引用 | 使用带延迟引用的类型别名 |
评论
支持 Markdown