Skip to content

createPropertyDecorator

awekrx edited this page May 29, 2026 · 1 revision

createPropertyDecorator

Import

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

Category

  • core

Use Case

Build reusable property decorators for get/set behavior.

Replaces

  • Repeated Object.defineProperty boilerplate
  • Scattered hidden-state handling code

Example 1

Without decorator

function normalized() {
  return function (target: object, key: string | symbol) {
    let value: unknown;
    Object.defineProperty(target, key, {
      get() { return value; },
      set(next) { value = typeof next === 'string' ? next.trim() : next; },
      enumerable: true,
      configurable: true,
    });
  };
}

With decorator

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

const normalized = () =>
  createPropertyDecorator({
    set: ({ value, setValue }) => {
      setValue(typeof value === 'string' ? value.trim() : value);
    },
  });

Why better

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

Example 2

Without decorator

function readonlyAfterFirstSet() {
  return function (target: object, key: string | symbol) {
    let initialized = false;
    let value: unknown;
    Object.defineProperty(target, key, {
      get() { return value; },
      set(next) {
        if (initialized) throw new Error('readonly');
        initialized = true;
        value = next;
      },
    });
  };
}

With decorator

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

const readonlyAfterFirstSet = () =>
  createPropertyDecorator({
    set: ({ entry, value, setValue }) => {
      if (entry.hasValue) throw new Error('readonly');
      setValue(value);
    },
  });

Why better

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

Clone this wiki locally