جافاسكريبت - كيف يمكن استخدام الانعكاس في تايبسكريبت بطريقة مشابهة للجافا؟


أنا أستخدم الانعكاس في جافا للحصول على بعض المعلومات من التعليمة التوضيحية TestNG كما في مقطع الكود أدناه:

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

حاليًا، لدي إطار عمل Jest مع إضافة مزخرفة بـ Jest للمساعدة في استخدام التعليقات التوضيحية.

كيف يمكنني تكرار نفس طريقة الانعكاس في جافا ولكن في تايب سكريبت لجمع هذه المعلومات من التعليقات التوضيحية؟

الإجابة رقم 1

يرجى الاطلاع على Decorators و Reflect Metadata API في Typescript، والتي يمكن أيضًا تفعيلها لمترجم 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

تحقق من الملخص. يمكنك إنشاء نسخ من تلك الأنواع (حتى لو كانت من ملفات مختلفة) واستدعاء تلك الطرق. أيضًا يمكن أن تحتوي تلك المزخرفات على وسائط بحيث يمكنك تصفية الطرق التي لها نفس المزخرفات ولكن بوسائط مختلفة.

tst-reflect لا يزال قيد التطوير لذا تتطلب عمليات البحث العالمية عن الأنواع وجود تلك المزخرفات @reflect أو المزخرفات المخصصة مع وسم JSDoc @reflect؛ السبب هو تحسين حجم البيانات الوصفية المولدة. ولكن هناك مشكلة في توسيع التكوين بواسطة أنماط glob "include" والتي ستشمل جميع الأنواع من جميع الوحدات التي تطابق تلك الأنماط.

ملاحظة: اطلع على ويكي الإعدادات واستخدم هذا الإعداد:

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
        }
    }
}