This is a reflection library for TypeScript!
Do you hate writing decorators but love their power? How about all the work required to get the type a method returns or a parameter expects? This library makes it simple to write decorators, and to access metadata and type information from classes, methods, properties, and parameters.
Install the package into your project:
npm install @baileyherbert/reflection
Then configure your tsconfig.json
file as follows if you want metadata and type reflection:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
}
}
Check out the documentation website.
Check out this pointless example that iterates over the methods, properties, and parameters in a class.
import { ClassName } from './ClassName';
const ref = new ReflectionClass(ClassName);
for (const method of ref.getMethods()) {
const returns = method.getReturnType();
const params = method.getParameters().map(param => param.getType());
console.log('Method:', method.name);
console.log('Returns:', returns);
console.log('Accepts:', params);
}
for (const property of ref.getProperties()) {
if (property.hasMetadata('key')) {
// Create something cool!
}
}
This is a very oversimplified example that creates instances of a class's expected dependencies and then constructs a new instance with them.
// Get our constructor method in a line
const constructor = reflection.getConstructorMethod();
// Then get its parameter types and instantiate them
const params = constructor.getParameters();
const types = params.map(param => param.getType());
const objects = types.map(type => new type());
// Voila!
const instance = reflection.create(objects);
Setting metadata doesn't have to be difficult. Just use the included @Meta()
decorator.
This has a few advantages. Most importantly, it writes metadata in a consistent format that the reflection library can natively understand, including for properties and parameters.
import { Meta } from '@baileyherbert/reflection';
const Custom = (value: any) => Meta('key', value);
@Meta('key', 'value')
export class Example {
@Custom('value')
public method() {
}
}
const ref = new ReflectionClass(Example);
ref.getMetadata('key'); // 'value'
const method = ref.getMethod('method')!;
method.getMetadata('key'); // 'value'