reflect-metadata 是一个用于在 TypeScript 中实现元数据反射的库。它允许你在类、方法、属性等上附加元数据,并在运行时通过反射机制访问这些元数据。
安装
首先,需要安装 reflect-metadata 库。
npm install reflect-metadata
基本用法
首先需要修改工程的 tsconfig.json 文件,添加以下配置:
{
...
"target": "ES5",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
...
}
在模块中导入 reflect-metadata
import 'reflect-metadata';
使用 @Reflect.metadata 装饰器来定义元数据。例如,可以在类的方法上定义元数据:
class Example {
@Reflect.metadata('design:type', String)
greet(name: string): string {
return `Hello, ${name}!`;
}
}
使用 Reflect.getMetadata 方法来访问元数据。
import {Example} from './example';
const example = new Example();
const type = Reflect.getMetadata('design:type', example, 'greet');
console.log(type); // 输出: [Function: String]
自定义元数据key
定义元数据
import 'reflect-metadata';
@Reflect.metadata('class', 'ExampleClass')
class Example {
@Reflect.metadata('method', 'greetMethod')
greet(name: string): string {
return `Hello, ${name}!`;
}
}
访问类元数据
import {Example} from './example';
const classMetadata = Reflect.getMetadata('class', Example);
console.log(classMetadata);
const methodMetadata = Reflect.getMetadata('method', Example.prototype, 'greet');
console.log(methodMetadata);
输出结果
ExampleClass
greetMethod
自定义装饰器
分别定义类装饰器和方法装饰器
import "reflect-metadata";
function classDecorator(): ClassDecorator {
return target => {
Reflect.defineMetadata('classMetaData', 'value for classMetaData', target);
};
}
function methodDecorator(): MethodDecorator {
return (target, key, descriptor) => {
Reflect.defineMetadata('methodMetaData', 'value for methodMetaData', target, key);
};
}
使用装饰器
@classDecorator()
export class Example {
@methodDecorator()
greet(name: string): string {
return `Hello, ${name}!`;
}
}
获取元数据
console.log(Reflect.getMetadata('classMetaData', Example));
console.log(Reflect.getMetadata('methodMetaData', new Example(), 'greet'));
输出结果
value for classMetaData
value for methodMetaData
与装饰器一起使用实现方法拦截
reflect-metadata 可以与装饰器一起使用,以实现更复杂的元数据管理。例如,我们可以创建一个自定义装饰器来记录方法调用次数:
定义方法拦截装饰器
import "reflect-metadata";
function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Before calling ${propertyKey} with arguments: ${args}`);
const result = originalMethod.apply(this, args);
console.log(`Result of ${propertyKey}: ${result}`);
return result;
};
return descriptor;
}
是使用方法拦截装饰器
class Example {
@logMethod
greet(name: string): string {
return `Hello, ${name}!`;
}
}
调用方法
import {Example} from './example';
const example = new Example();
example.greet('World');
输出结果
Before call method greet with arguments: World
Result of greet: Hello, World!
总结
reflect-metadata 是一个强大的库,它可以在 TypeScript 中实现元数据反射。通过使用装饰器和反射机制,可以轻松地在运行时访问和操作元数据,从而实现更灵活和强大的功能。