javascript - Ako používať Reflection v TypeScripte podobne ako v Jave?
Používam refleksiu v Jave na získanie niektorých informácií z anotácie TestNG, ako je to v kóde nižšie:
Reflections reflections = new Reflections("", new MethodAnnotationsScanner())
Set<Method> annotated = reflections.getMethodsAnnotatedWith(Test.class)
V súčasnosti mám framework Jest s plug-inom dekorovaným Jest, ktorý pomáha pri používaní anotácií.
Ako môžem replikovať tú istú metódu reflexie v Jave, ale v TypeScripte, aby som získal tieto informácie z anotácií?
Odpoveď č. 1
Pozrite si, prosím, dekorátory Typescriptu + Reflect Metadata API, ktoré je možné tiež povoliť pre TS kompilátor. Nefunguje presne ako Java, ale stále môžete zhromaždiť požadované informácie o anotovaných entitách. Malý príklad, ako zhromaždiť anotované triedy:
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);
Odpoveď č. 2
Vyskúšajte moju knižnicu tst-reflect. Je to pomerne pokročilý reflektujúci systém pre TypeScript ().
Toto by malo byť ekvivalentom vášho Java kódu:
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);
}
Výstup
foo in A
bar in B
Skontrolujte synopsu. Ste schopní vytvárať inštancie týchto typov (aj keď sú z rôznych súborov) a volat tie metódy. Tiež tieto dekorátory môžu mať argumenty, takže budete schopní filtrovať metódy s rovnakými dekorátormi, ale rôznymi argumentmi.
tst-reflect je stále vo vývoji, takže globálne vyhľadávanie typov vyžaduje použitie týchto dekorátorov @reflect alebo vlastných dekorátorov s JSDoc tagom @reflect; dôvodom je optimalizácia veľkosti generovaných metadát. Ale existuje problém s rozšírením konfigurácie pomocou glob vzorov „include“, ktoré zahrnú všetky typy zo všetkých modulov, ktoré tieto globy zodpovedajú.
PS: Pozrite si konfiguračnú wiki a použite túto konfiguráciu:
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
}
}
}
