如何在TypeScript中实现类似Java的反射功能采集装饰器注解信息
实现步骤
1. 前置依赖与配置
首先确保安装必要依赖:npm install reflect-metadata glob @types/glob -D
修改tsconfig.json开启装饰器和元数据发射配置:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } }
在项目入口文件最顶部引入import 'reflect-metadata',这是元数据存储的基础依赖。
2. 核心实现逻辑
Java里的Reflections工具核心做了两件事:扫描指定路径下所有类、过滤出带指定注解的方法,TS中我们按相同逻辑复刻即可:
jest-decorated的@Test装饰器会自动在反射元数据中存储标记,我们可以通过Reflect相关API判断方法是否被@Test修饰,完整代码示例如下:
import 'reflect-metadata'; import * as glob from 'glob'; import * as path from 'path'; import { Test } from 'jest-decorated'; // 自定义扫描类,对应Java中的Reflections实例 class AnnotationScanner { // 扫描指定目录下所有带@Test注解的方法 scanMethodsWithTestAnnotation(scanPath: string): Set<Function> { const matchedMethods = new Set<Function>(); // 匹配测试文件,可根据项目规则调整后缀规则 const filePaths = glob.sync(path.join(scanPath, '**/*.test.ts')); filePaths.forEach(filePath => { // 加载文件导出的所有模块 const fileExports = require(path.resolve(filePath)); Object.values(fileExports).forEach(exportItem => { // 只处理类类型的导出 if (typeof exportItem === 'function' && exportItem.prototype) { // 遍历类的所有自有方法 const methodNames = Object.getOwnPropertyNames(exportItem.prototype); methodNames.forEach(methodName => { const method = exportItem.prototype[methodName]; if (typeof method === 'function') { // 判断方法是否被@Test注解修饰 if (Reflect.hasMetadata(Test.name, exportItem.prototype, methodName)) { matchedMethods.add(method); } } }); } }); }); return matchedMethods; } } // 使用示例,和Java用法逻辑对齐 const scanner = new AnnotationScanner(); // 传入要扫描的测试文件根目录,比如项目下的test目录 const annotatedMethods = scanner.scanMethodsWithTestAnnotation('./test'); // 输出所有带@Test注解的方法 console.log(annotatedMethods);
3. 注意事项
- 如果你的测试文件后缀是
.js/.tsx,调整glob的匹配规则即可 - 如果要扫描其他自定义注解,替换判断逻辑中的
Test.name为对应的装饰器类名即可 - 扫描路径建议使用绝对路径避免解析异常
- 如果识别不到注解,可将判断逻辑中的元数据key替换为
Test本身再尝试,不同装饰器实现的元数据存储key会有差异
内容的提问来源于stack exchange,提问作者johny
相关产品推荐
相关产品推荐

