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

如何使用TypeScript Compiler API将type转换为带class-validator声明的class

TypeScript type 转带 class-validator 装饰器的 class 实现方案

你可以直接使用TypeScript官方提供的Compiler API完成这个需求,这是兼容性和扩展性最好的实现方式,具体步骤如下:

核心实现步骤

  • 安装依赖并初始化编译实例
    首先安装typescript依赖,创建编译程序加载你要处理的目标文件,获取对应的AST节点:
    import * as ts from 'typescript';
    
    const targetFilePath = './你的目标文件路径.ts';
    const program = ts.createProgram([targetFilePath], {
      strict: true,
    });
    const sourceFile = program.getSourceFile(targetFilePath)!;
    
  • 遍历AST匹配类型别名节点
    遍历源文件的AST节点,匹配type xxx = {}格式的类型别名声明,你说的typeNode就是类型别名下的type属性,当它是对象字面量类型时就能拿到所有属性信息:
    ts.forEachChild(sourceFile, (node) => {
      // 匹配类型别名声明,且类型是对象字面量
      if (ts.isTypeAliasDeclaration(node) && ts.isTypeLiteralNode(node.type)) {
        const className = node.name.getText();
        // 过滤出所有属性
        const properties = node.type.members.filter(ts.isPropertySignature);
        // 后续生成class逻辑写在这里
      }
    });
    
  • 维护类型和装饰器的映射关系
    提前定义TS基础类型对应class-validator装饰器的映射表,遇到对应类型直接匹配即可,可选属性可以额外加@IsOptional()装饰器:
    const typeDecoratorMap: Record<string, string> = {
      string: '@IsString()',
      number: '@IsNumber()',
      boolean: '@IsBoolean()',
      Array: '@IsArray()',
      // 可自行扩展联合类型、自定义类型等映射规则
    };
    
  • 生成并输出class代码
    你可以直接拼接字符串生成代码,也可以用TS自带的factory和printer生成规范的代码节点,避免语法错误:
    const factory = ts.factory;
    // 生成class声明节点
    const classNode = factory.createClassDeclaration(
      undefined,
      factory.createIdentifier(className),
      undefined,
      undefined,
      properties.map((prop) => {
        const propTypeName = prop.type!.getText();
        const decorators = [];
        // 可选属性加@IsOptional()
        if (prop.questionToken) {
          decorators.push(
            factory.createDecorator(
              factory.createCallExpression(factory.createIdentifier('IsOptional'), undefined, [])
            )
          );
        }
        // 加对应类型的装饰器
        decorators.push(
          factory.createDecorator(
            factory.createCallExpression(
              factory.createIdentifier(typeDecoratorMap[propTypeName].replace(/^@|\(\)$/g, '')),
              undefined,
              []
            )
          )
        );
        // 生成属性节点
        return factory.createPropertyDeclaration(
          decorators,
          prop.name.getText(),
          undefined,
          prop.type,
          undefined
        );
      })
    );
    // 打印为代码文本
    const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
    const outputCode = printer.printNode(ts.EmitHint.Unspecified, classNode, sourceFile);
    console.log(outputCode);
    

简化方案

如果不想处理底层Compiler API逻辑,可以用封装好的ts-morph库,它的API更简单易用,十几行代码就能完成相同的转换逻辑。如果只是处理简单固定的类型,也可以直接写正则匹配替换,不过这种方式不支持复杂的嵌套、联合类型场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:03:00