Decorators
Overview
The @antelopejs/interface-core/decorators module provides factory functions for creating type-safe TypeScript decorators. These factories handle the boilerplate of splitting decorator arguments from factory arguments, producing reusable, parameterized decorators for classes, properties, methods, and parameters.
Import
import {
MakeClassDecorator,
MakePropertyDecorator,
MakeMethodDecorator,
MakeParameterDecorator,
} from "@antelopejs/interface-core/decorators";
Types
The module exports several utility types used throughout the decorator system:
| Type | Description |
|---|---|
Func<A, R> | Generic function type with arguments A and return type R |
Class<T, A> | Class constructor that creates instances of type T |
ClassDecorator<C> | Decorator applied to class constructors |
PropertyDecorator | Decorator applied to class properties |
MethodDecorator | Decorator applied to class methods and accessors |
ParameterDecorator | Decorator applied to method parameters |
Single-target decorator factories
MakeClassDecorator
Creates a decorator factory that targets classes. The handler receives the decorated class as its first argument, followed by any factory parameters.
import { MakeClassDecorator } from "@antelopejs/interface-core/decorators";
const Entity = MakeClassDecorator((target: Function, tableName: string) => {
Reflect.defineMetadata("table", tableName, target);
});
@Entity("users")
class User {
name!: string;
}
MakePropertyDecorator
Creates a decorator factory that targets properties. The handler receives the target object and property key, followed by factory parameters.
import { MakePropertyDecorator } from "@antelopejs/interface-core/decorators";
const Column = MakePropertyDecorator((target: any, key: PropertyKey, columnName: string) => {
const columns = Reflect.getOwnMetadata("columns", target) || [];
columns.push({ key, columnName });
Reflect.defineMetadata("columns", columns, target);
});
class User {
@Column("user_name")
name!: string;
}
MakeMethodDecorator
Creates a decorator factory that targets methods and accessors. The handler receives the target object, method key, and property descriptor, followed by factory parameters.
import { MakeMethodDecorator } from "@antelopejs/interface-core/decorators";
const Log = MakeMethodDecorator(
(target: any, key: PropertyKey, descriptor: PropertyDescriptor, level: string) => {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`[${level}] Calling ${String(key)}`);
return original.apply(this, args);
};
},
);
class Service {
@Log("info")
process() {
// ...
}
}
MakeParameterDecorator
Creates a decorator factory that targets method parameters. The handler receives the target object, method key, and parameter index, followed by factory parameters.
import { MakeParameterDecorator } from "@antelopejs/interface-core/decorators";
const Inject = MakeParameterDecorator(
(target: any, key: PropertyKey, index: number, token: string) => {
const injections = Reflect.getOwnMetadata("injections", target, key) || [];
injections[index] = token;
Reflect.defineMetadata("injections", injections, target, key);
},
);
class Controller {
handle(@Inject("db") db: any) {
// ...
}
}
Multi-target decorator factories
For decorators that apply to multiple targets, the module provides combined factory functions. These detect the decorator context automatically based on the number and types of arguments received.
| Factory | Targets |
|---|---|
MakePropertyAndClassDecorator | Properties and classes |
MakeMethodAndClassDecorator | Methods and classes |
MakeMethodAndPropertyDecorator | Methods and properties |
MakeMethodAndPropertyAndClassDecorator | Methods, properties, and classes |
MakeParameterAndClassDecorator | Parameters and classes |
MakeParameterAndPropertyDecorator | Parameters and properties |
MakeParameterAndPropertyAndClassDecorator | Parameters, properties, and classes |
MakeParameterAndMethodDecorator | Parameters and methods |
MakeParameterAndMethodAndClassDecorator | Parameters, methods, and classes |
MakeParameterAndMethodAndPropertyDecorator | Parameters, methods, and properties |
MakeParameterAndMethodAndPropertyAndClassDecorator | Parameters, methods, properties, classes |
Example: method and class decorator
import { MakeMethodAndClassDecorator } from "@antelopejs/interface-core/decorators";
const Track = MakeMethodAndClassDecorator(
(target: any, key: PropertyKey | undefined, descriptor: PropertyDescriptor | undefined, category: string) => {
if (descriptor) {
// Applied to a method
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`[${category}] ${String(key)} called`);
return original.apply(this, args);
};
} else {
// Applied to a class
Reflect.defineMetadata("trackCategory", category, target);
}
},
);
@Track("api")
class ApiController {
@Track("endpoint")
getUsers() {
// ...
}
}
When applied to a class, the key and descriptor arguments are undefined. When applied to a method, all three arguments are provided.