UNPKG

macroable

Version:

A simple ES6 class that can be extended to provide macros and getters functionality

105 lines (104 loc) 3.4 kB
/** * Shape of the Macro function */ declare type MacroFn<T, Args extends any[], ReturnValue extends any> = (this: T, ...args: Args) => ReturnValue; /** * Shape of the Getter function */ declare type GetterFn<T, ReturnValue extends any> = (this: T) => ReturnValue; /** * Returns the typed variation of the macro by inspecting the * interface declaration */ declare type GetMacroFn<T, K> = K extends keyof T ? T[K] extends (...args: infer A) => infer B ? MacroFn<T, A, B> : MacroFn<T, any[], any> : MacroFn<T, any[], any>; /** * Returns the typed variation of the getter by inspecting the * interface declaration */ declare type GetGetterFn<T, K> = K extends keyof T ? GetterFn<T, T[K]> : GetterFn<T, any>; /** * Shape of the macroable constructor */ export interface MacroableConstructorContract<T extends any> { macro<K extends string>(name: K, callback: GetMacroFn<T, K>): void; getter<K extends string>(name: K, callback: GetGetterFn<T, K>, 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<any, any[], any>; }; protected static getters: { [key: string]: GetterFn<any, any>; }; 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<T extends any, K extends string>(this: { new (...args: any): T; }, name: string, callback: GetMacroFn<T, K>): void; /** * Return the existing macro or null if it doesn't exists */ static getMacro(name: string): MacroFn<any, any[], any> | 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<T extends any, K extends string>(this: { new (...args: any): T; }, name: string, callback: GetGetterFn<T, K>, singleton?: boolean): void; /** * Return the existing getter or null if it doesn't exists */ static getGetter(name: string): GetterFn<any, any> | 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 {};