【问题标题】:How to use Reflection in typescript similarly like in java?如何像在 java 中一样在 typescript 中使用反射?
【发布时间】:2022-02-14 10:09:01
【问题描述】:

我在 Java 中使用反射从 TestNG 注释中获取一些信息,如下面的代码 sn-p:

Reflections reflections = new Reflections("", new MethodAnnotationsScanner())
Set<Method> annotated = reflections.getMethodsAnnotatedWith(Test.class)

目前,我有一个带有 jest 装饰插件的 jest 框架来帮助使用注释。

如何在 Java 中但在 typescript 中复制相同的反射方法以从注释中收集此信息?

【问题讨论】:

  • 您想要从 java 类中获取注释信息的 javascript 代码吗?我认为这是不可能的。
  • srry 打字稿

标签: javascript java reflection jestjs ts-jest


【解决方案1】:

请看一下 Typescript 的Decorators + Reflect Metadata API,也可以为 TS 编译器启用。它的工作方式与 Java 不完全相同,但您仍然可以收集有关带注释的实体的所需信息。如何收集带注释的类的小例子:

const myTypes: any[] = []

@annotation
class MyClass {
  type = "report";
  title: string;
 
  constructor(t: string) {
    this.title = t;
  }
}

function annotation(constructor: Function) {
    myTypes.push(constructor)
}

console.log('All annotated classes', myTypes);

【讨论】:

    【解决方案2】:

    试试tst-reflect。 它是非常先进的 TypeScript 反射系统(使用自定义 typescript 转换器插件)。

    这应该等同于您的 Java 代码:

    import {
        reflect,
        Type
    } from "tst-reflect";
    
    // Some decorator...
    function test(_, __)
    {
    }
    
    @reflect()
    class A
    {
        @test
        foo()
        {
            return 0;
        }
    
        bar()
        {
            return "lorem ipsum";
        }
    }
    
    @reflect()
    class B
    {
        @test
        bar()
        {
            return "lorem ipsum";
        }
    }
    
    @reflect()
    class C
    {
        baz()
        {
            return "lorem ipsum";
        }
    }
    
    const decoratedMethods = Type.getTypes()
        .flatMap(type => type.getMethods().map(method => ({ method, type })))
        .filter(entry => entry.method.getDecorators().some(decorator => decorator.name == "test"));
    
    for (let entry of decoratedMethods)
    {
        console.log(entry.method.name, "in", entry.type.name);
    }
    

    输出

    foo in A
    bar in B
    

    检查Synopsis。 您可以创建这些类型的实例(即使它们来自不同的文件)并调用这些方法。 这些装饰器也可以有参数,因此您将能够过滤具有相同装饰器但参数不同的方法。

    tst-reflect 仍在开发中,因此类型的全局查找需要那些 @reflect 装饰器或带有 @reflect JSDoc 标签的自定义装饰器;原因是生成的元数据的大小优化。但是有一个 issue 可以通过“包含”glob 模式扩展配置,该模式将包括与该 glob 匹配的所有模块中的所有类型。

    PS:查看configuration wiki并使用此配置:

    tsconfig.json

    {
        "compilerOptions": {
            // your options...
    
            // ADD THIS!
            "plugins": [
                {
                    "transform": "tst-reflect-transformer"
                }
            ]
        },
        // ADD THIS!
        "reflection": {
            "metadata": {
                "type": "typelib" // this mode will generate and auto-import library with generated reflection metadata
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-18
      • 2021-06-20
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多