Skip to content

Modern Decorators

Goal

Create a standard TypeScript method decorator that validates its application target and contributes to class metadata without accessing the class constructor.

Implementation

ts
import {
    Methods,
    getMetadataContainer,
} from '@litert/decorator';

function route(path: string): Methods.ICallbackFn {

    return Methods.withArgsCheck((_method, ctx) => {
        ctx.metadata!['route:' + String(ctx.name)] = path;
    });
}

class Controller {

    @route('/users')
    public listUsers(): void {}
}

const metadata = getMetadataContainer(Controller);
console.log(metadata.get('route:listUsers'));

Example code

Decorator kindExample
ClassClass.ts
MethodMethod.ts
PropertyProperty.ts
AccessorAccessor.ts
GetterGetter.ts
SetterSetter.ts
Static methodStaticMethod.ts
Static propertyStaticProperty.ts
Static accessorStaticAccessor.ts
Static getterStaticGetter.ts
Static setterStaticSetter.ts

Notes

StepReason
Use Methods.withArgsCheckThe generated decorator throws when applied to the wrong kind of element.
Write to ctx.metadataModern member decorators do not receive the owning class constructor or prototype. The metadata object is the shared class configuration container.
Read through getMetadataContainerApplication code can read the completed class metadata after the class has been defined.

For larger decorators, prefer a single metadata key that stores a structured class configuration object. Let class, instance member, and static member decorators add their own entries to that object, then read the final result from getMetadataContainer(YourClass).