/** * Shape of the Macro function */ declare type MacroFn = (this: T, ...args: Args) => ReturnValue; /** * Shape of the Getter function */ declare type GetterFn = (this: T) => ReturnValue; /** * Returns the typed variation of the macro by inspecting the * interface declaration */ declare type GetMacroFn = K extends keyof T ? T[K] extends (...args: infer A) => infer B ? MacroFn : MacroFn : MacroFn; /** * Returns the typed variation of the getter by inspecting the * interface declaration */ declare type GetGetterFn = K extends keyof T ? GetterFn : GetterFn; /** * Shape of the macroable constructor */ export interface MacroableConstructorContract { macro(name: K, callback: GetMacroFn): void; getter(name: K, callback: GetGetterFn, singleton?: boolean): void; hydrate(): void; } /** * Macroable is an abstract class to add ability to extend your class * prototype using better syntax. * * Macroable has handful of benefits over using traditional `prototype` approach. * * 1. Methods or properties added dynamically to the class can be removed using `hydrate` method. * 2. Can define singleton getters. */ export declare abstract class Macroable { protected static macros: { [key: string]: MacroFn; }; protected static getters: { [key: string]: GetterFn; }; constructor(); /** * Add a macro to the class. This method is a better to manually adding * to `class.prototype.method`. * * Also macros added using `Macroable.macro` can be cleared anytime * * @example * ```js * Macroable.macro('getUsername', function () { * return 'virk' * }) * ``` */ static macro(this: { new (...args: any): T; }, name: string, callback: GetMacroFn): void; /** * Return the existing macro or null if it doesn't exists */ static getMacro(name: string): MacroFn | undefined; /** * Returns a boolean telling if a macro exists */ static hasMacro(name: string): boolean; /** * Define a getter, which is invoked everytime the value is accessed. This method * also allows adding single getters, whose value is cached after first time * * @example * ```js * Macroable.getter('time', function () { * return new Date().getTime() * }) * * console.log(new Macroable().time) * * // Singletons * Macroable.getter('time', function () { * return new Date().getTime() * }, true) * * console.log(new Macroable().time) * ``` */ static getter(this: { new (...args: any): T; }, name: string, callback: GetGetterFn, singleton?: boolean): void; /** * Return the existing getter or null if it doesn't exists */ static getGetter(name: string): GetterFn | undefined; /** * Returns a boolean telling if a getter exists */ static hasGetter(name: string): boolean; /** * Cleanup getters and macros from the class */ static hydrate(): void; } export {};