swagger自动转ts小工具

61 阅读1分钟

写过一些简单的CLI工具,比如一个自动根据API的Swagger文档,生成TypeScript类型定义的小脚本。

swagger自动转ts


swagger

啥是swagger。

swagger 是 接口说明书

一般是json或者yaml文件.

{
  'openapi': '3.0.0',
  'info': {
    'title': 'blog api',
    'version': '1.0.0'
  },
  'paths': {
    '/users/{id}': {
      'get': {
        'parameters': [
          {
            'name': 'id',
            'in': 'path',
            'required': true,
            'schema': {
              'type': 'integer'
            }
          }
        ],
        'responses': {
          '200': {
            'description': '成功返回用户',
            'content': {
              'application/json': {
                'schema': {
                  '$ref': '#/components/schemas/User'
                }
              }
            }
          }
        }
      }
    }
  },
  
  'components': {
    'schemas': {
      'User': {
        'type': 'object',
        'properties': {
          'id': { 'type': 'integer' },
          'name': { 'type': 'string' },
          'email': { 'type': 'string' }
        }
      }
    }
  }
  
}

我要自动转成:

// types.d.ts

export interface User {
  id: number;
  name: string;
  email?: string;
}

写node小工具:(就是找规律 循环 自动输出固定的有规律的东西)

// generate-types.ts

import fs from 'fs';

// swagger -> ts 类型的映射 
function swaggerTypeToTs(type: string): string {
  // 用switch去映射
  switch(type) {
  
    case 'string':
      return 'string';
      
    case 'integer':
    case 'number':
      return 'number';
    
    case 'boolean':
      return 'boolean';
    
    case 'array':
      return "any[]"; // 先简化处理,如果有时间后续扩展里面的不同情况
    
    case 'object':
      return 'Record<string, any>';
      
    default:
      return 'any';
  }
}

function generateInterface(name: string, schema: any): string {
  if (!schema.properties) {
    return `export interface ${name} { [key: string]: any }\n`;
  }
  
  const fields = Object.entries(schema.properties)
    .map(([key, value]: [string, any]) => {
    
      const optional = schema.required?.includes(key) ? "" : "?";
      const tsType = value.type
        ? swaggerTypeToTs(value.type)
        : value.$ref
        ? value.$ref.split('/').pop() // 取 ref 名称
        : 'any';
      
      return ` ${key}${optional}: ${tsType}`;
      
    }).join('\n')
}

// 主逻辑
function main() {
  const swagger = JSON.parse(fs.readFileSync("swagger.json", "utf-8"));
  const schemas = swagger.components?.schemas;

  if (!schemas) {
    console.error("❌ 没有找到 components.schemas");
    return;
  }

  let output = "";
  for (const [name, schema] of Object.entries(schemas)) {
    output += generateInterface(name, schema as any) + "\n";
  }

  fs.writeFileSync("types.d.ts", output, "utf-8");
  console.log("✅ 已生成 types.d.ts");
}

main();