You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何转换TypeScript接口中带Id后缀的属性并生成新文件?

最优实现方案:使用ts-morph处理TypeScript接口转换

核心思路

直接操作TypeScript的抽象语法树(AST)是最可靠的方案,能避免正则表达式在复杂场景下的误匹配问题。ts-morph是对TypeScript Compiler API的封装,用它可以轻松解析、修改和生成TS代码。

步骤实现

1. 安装依赖

npm install ts-morph --save-dev

2. 编写转换脚本

以下脚本支持两种转换模式:

  • replace:替换原xxxId属性为对应的关联对象(第一种形式)
  • keep:保留原xxxId属性并新增关联对象(第二种形式)
import { Project, InterfaceDeclaration } from "ts-morph";

async function convertInterfaces() {
  // 初始化TS项目,关联本地tsconfig
  const project = new Project({ tsConfigFilePath: "./tsconfig.json" });
  
  // 加载源文件与创建输出文件
  const sourceFile = project.addSourceFileAtPath("./src/original.ts");
  const outputFile = project.createSourceFile("./src/converted.ts", "", { overwrite: true });

  // 复制基础接口(User/Product/Account)到输出文件
  sourceFile.getInterfaces().forEach(iface => {
    // 可根据需求调整判断逻辑,比如匹配所有带xxxId属性的接口
    if (!["MyType"].includes(iface.getName())) {
      outputFile.addInterface(iface.getStructure());
    }
  });

  // 获取目标转换接口
  const targetInterface = sourceFile.getInterface("MyType");
  if (!targetInterface) throw new Error("未找到目标接口MyType");

  // 设置转换模式:replace / keep
  const conversionMode: "replace" | "keep" = "keep";
  const convertedProps: any[] = [];

  // 遍历原接口属性,生成转换后的属性列表
  targetInterface.getProperties().forEach(prop => {
    const propName = prop.getName();
    if (propName === "id") {
      convertedProps.push(prop.getStructure());
      return;
    }

    if (propName.endsWith("Id")) {
      // 提取关联类型名(userId → User)
      const typePrefix = propName.slice(0, -2);
      const typeName = typePrefix.charAt(0).toUpperCase() + typePrefix.slice(1);
      
      // 添加关联对象属性
      convertedProps.push({ name: typePrefix, type: typeName });
      
      // 保留原Id属性(仅keep模式)
      if (conversionMode === "keep") {
        convertedProps.push(prop.getStructure());
      }
    } else {
      // 非Id结尾属性直接保留
      convertedProps.push(prop.getStructure());
    }
  });

  // 添加转换后的接口到输出文件
  outputFile.addInterface({
    name: targetInterface.getName(),
    isExported: true,
    properties: convertedProps
  });

  // 保存结果
  await outputFile.save();
}

convertInterfaces().catch(console.error);

其他方案的局限性

  • 正则表达式:仅适合极简单的代码结构,若遇到注释中的xxxId、字符串字面量里的Id、嵌套接口等场景,会出现误匹配或漏处理,可靠性极低。
  • 手动修改:适合单次操作,但无法批量处理或自动化维护,效率低下。

方案优势

  • 基于官方TS Compiler API,能准确解析所有TS语法结构,避免正则的局限性。
  • 代码逻辑清晰,可扩展性强(比如新增批量转换所有符合条件的接口、自定义类型映射规则等)。
  • 输出代码格式规范,与原代码风格一致。

内容的提问来源于stack exchange,提问作者Sergino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:43:12