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

如何将TypeScript类型提取至独立包?(React项目场景)

自动化提取TypeScript类型到独立包的方法

以下是几种无需手动复制粘贴的自动化方案,适合处理大量文件的类型迁移:

1. 使用 ts-morph 编写自定义脚本

ts-morph是操作TypeScript AST的工具,能精准识别并提取类型定义。

步骤:

  • 安装依赖:npm install ts-morph typescript --save-dev
  • 编写脚本示例:
    import { Project } from "ts-morph";
    
    const project = new Project({
      tsConfigFilePath: "./tsconfig.json", // 指向你的项目TS配置文件
    });
    
    // 遍历目标文件
    const sourceFiles = project.getSourceFiles("src/**/*.tsx");
    const targetDir = "./packages/types/src"; // 独立包的源码目录
    
    // 创建汇总类型的目标文件
    const targetFile = project.createSourceFile(
      `${targetDir}/index.ts`,
      "",
      { overwrite: true }
    );
    
    sourceFiles.forEach((file) => {
      // 提取所有可导出的类型定义
      const types = [
        ...file.getInterfaces().filter(i => i.isExported()),
        ...file.getTypeAliases().filter(t => t.isExported()),
        ...file.getEnums().filter(e => e.isExported()),
      ];
    
      types.forEach((type) => {
        // 根据类型种类添加到目标文件
        switch(type.getKindName()) {
          case "InterfaceDeclaration":
            targetFile.addInterface({
              name: type.getName(),
              properties: type.getProperties().map(p => ({
                name: p.getName(),
                type: p.getTypeNode()?.getText(),
                isOptional: p.isOptional()
              })),
              isExported: true
            });
            break;
          case "TypeAliasDeclaration":
            targetFile.addTypeAlias({
              name: type.getName(),
              type: type.getTypeNode()?.getText(),
              isExported: true
            });
            break;
          case "EnumDeclaration":
            targetFile.addEnum({
              name: type.getName(),
              members: type.getMembers().map(m => ({
                name: m.getName(),
                value: m.getInitializer()?.getText()
              })),
              isExported: true
            });
            break;
        }
    
        // 移除原文件中的该类型(可选,按需操作)
        type.remove();
      });
    });
    
    // 保存所有修改
    project.save();
    
  • 运行脚本:npx ts-node ./scripts/extract-types.ts
  • 优势:精准控制提取范围,支持自定义过滤规则,可同步清理原文件中的类型定义。

2. 使用 jscodeshift 编写Codemod

jscodeshift是批量代码重构工具,适合处理大规模类型迁移,还能自动更新导入语句。

步骤:

  • 安装依赖:npm install jscodeshift typescript --save-dev
  • 编写codemod脚本,识别类型定义并移动到目标文件,同时更新原文件的导入引用。
  • 运行codemod:npx jscodeshift -t ./codemods/extract-types.ts src/**/*.tsx
  • 优势:自动处理依赖导入的调整,适合复杂项目的类型迁移。

3. 利用TypeScript的declaration生成类型文件

如果只需要提取类型声明文件,可通过TS编译配置自动生成:

  • 修改项目的tsconfig.json:
    {
      "compilerOptions": {
        "declaration": true, // 生成.d.ts类型声明文件
        "declarationDir": "./packages/types/dist", // 输出到独立包目录
        "emitDeclarationOnly": true, // 仅生成声明文件,不编译JS
        "outDir": "./packages/types/dist"
      },
      "include": ["src/**/*.tsx"] // 指定要处理的文件范围
    }
    
  • 运行编译:tsc
  • 后续可在独立包中整理生成的.d.ts文件,比如合并到index.ts或保留原有目录结构。
  • 注意:此方法会生成所有类型声明,可能包含不需要的内容,需结合脚本过滤或手动清理。

注意事项

  • 检查依赖关系:部分类型可能依赖其他文件的类型,需确保目标包包含所有依赖类型,或调整导入路径。
  • 验证兼容性:提取完成后,在原项目中替换类型导入为新的独立包,确保编译无类型错误。
  • 版本控制:操作前提交代码到Git,方便异常时回滚。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:02:20