Skip to content

createClassDecorator

awekrx edited this page May 29, 2026 · 1 revision

createClassDecorator

Import

import { createClassDecorator } from '@dev-suite/decorators/createClassDecorator'

Category

  • core

Use Case

Build reusable class decorators from lifecycle hooks.

Replaces

  • Custom proxy/construct boilerplate per decorator
  • Inconsistent class decorator contracts

Example 1

Without decorator

function loggedClass() {
  return function <T extends new (...args: unknown[]) => unknown>(Ctor: T): T {
    return new Proxy(Ctor, {
      construct(target, args, newTarget) {
        console.log('create', target.name, args);
        return Reflect.construct(target, args, newTarget);
      },
    });
  };
}

With decorator

import { createClassDecorator } from '@dev-suite/decorators/createClassDecorator';

const loggedClass = () =>
  createClassDecorator({
    before: ({ target, args }) => {
      console.log('create', target.name, args);
    },
  });

Why better

  • Centralizes cross-cutting behavior.
  • Method/class/property code stays focused on domain logic.

Example 2

Without decorator

function measuredClass() {
  return function <T extends new (...args: unknown[]) => unknown>(Ctor: T): T {
    return new Proxy(Ctor, {
      construct(target, args, newTarget) {
        const start = Date.now();
        const instance = Reflect.construct(target, args, newTarget);
        console.log('ctor ms', Date.now() - start);
        return instance;
      },
    });
  };
}

With decorator

import { createClassDecorator } from '@dev-suite/decorators/createClassDecorator';

const measuredClass = () =>
  createClassDecorator({
    wrap: ({ invoke }) => {
      const start = Date.now();
      const instance = invoke();
      console.log('ctor ms', Date.now() - start);
      return instance;
    },
  });

Why better

  • Second scenario reuses same policy without duplication.
  • Behavior is more consistent and easier to audit.

Clone this wiki locally