[data-reveal]{opacity:1!important;transform:none!important}
Core

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:

TypeDescription
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
PropertyDecoratorDecorator applied to class properties
MethodDecoratorDecorator applied to class methods and accessors
ParameterDecoratorDecorator 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.

FactoryTargets
MakePropertyAndClassDecoratorProperties and classes
MakeMethodAndClassDecoratorMethods and classes
MakeMethodAndPropertyDecoratorMethods and properties
MakeMethodAndPropertyAndClassDecoratorMethods, properties, and classes
MakeParameterAndClassDecoratorParameters and classes
MakeParameterAndPropertyDecoratorParameters and properties
MakeParameterAndPropertyAndClassDecoratorParameters, properties, and classes
MakeParameterAndMethodDecoratorParameters and methods
MakeParameterAndMethodAndClassDecoratorParameters, methods, and classes
MakeParameterAndMethodAndPropertyDecoratorParameters, methods, and properties
MakeParameterAndMethodAndPropertyAndClassDecoratorParameters, 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.

Next steps

  • Metadata - Reflection-based metadata with GetMetadata
  • Proxies - Module-aware proxy classes