Skip to content

Metadata

With the introduction of Classes in TypeScript and ES6, there now exist certain scenarios that require additional features to support annotating or modifying classes and class members. Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript.

Installing

npm i @typeix/metadata --save

Creating Decorators

Defining custom decorators has not been easier, API will take care that metadataKeys are created correctly and passed to low level metadata api.

import {
    createClassDecorator,
    createParameterDecorator,
    createPropertyDecorator,
    createParameterAndPropertyDecorator,
    createMethodDecorator
} from "@typeix/metadata";

const Injectable = () => createClassDecorator(Injectable);
const Inject = (token?) => createParameterAndPropertyDecorator(Inject, {token});
const Produces = (type) => createMethodDecorator(Produces, {type});
const Render = (type) => createMethodDecorator(Produces, {type});
const PathParam = (value) => createParameterDecorator(Produces, {value});

@Injectable()
class AService {
}

@Injectable()
class BService {
}

@Injectable()
class RootController {
    @Inject() aService: AService;
    @Inject() bService: BService;

    @Produces("application/json")
    actionIndex(@Inject() first: AService, @Inject() second: BService) {
    }
}

@Injectable()
class HomeController extends RootController {

    @Render("home")
    actionHome(
        @Inject() first: AService,
        @Inject(BService) second: BService,
        @PathParam("name") name: string
    ) {
    }
}

const metadata: Array<IMetadata> = getAllMetadataForTarget(HomeController);

Interface IMetadata

  • args - are custom arguments passed by decorator
  • metadataKey - is unique decorator key auto generated by metadata api
  • type - class, method, property, parameter
  • decoratorType - (above type) + mixed is createParameterAndPropertyDecorator
  • decorator - actual reference to decorator Function
  • propertyKey - user defined method name or constructor
  • paramIndex - it's defined if decorator is parameter type
  • designType - value from design:type typescript metadata
  • designParam - values from design:paramtypes typescript metadata
  • designReturn - values from design:returntype typescript metadata
    export interface IMetadata {
        args: any;
        metadataKey: string;
        type?: string;
        decoratorType?: string;
        decorator?: Function;
        propertyKey?: string | symbol;
        paramIndex?: number;
        designType?: any;
        designParam?: any;
        designReturn?: any;
    }
    
    All metadata for target can be requested via getAllMetadataForTarget function, which returns list of metadata.
    eg.:
    [
        {
            args: {
                token: BService
            },
            decoratorType: "mixed",
            decorator: Inject,
            type: "parameter",
            metadataKey: `@typeix:parameter:Inject:1:${getDecoratorUUID(Inject)}`,
            paramIndex: 1,
            propertyKey: "actionHome",
            designParam: [
                AService,
                BService,
                String
            ]
        }
        ...
    ]