1 |
|
2 |
|
3 |
|
4 | declare type MacroFn<T, Args extends any[], ReturnValue extends any> = (this: T, ...args: Args) => ReturnValue;
|
5 |
|
6 |
|
7 |
|
8 | declare type GetterFn<T, ReturnValue extends any> = (this: T) => ReturnValue;
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | 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>;
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | declare type GetGetterFn<T, K> = K extends keyof T ? GetterFn<T, T[K]> : GetterFn<T, any>;
|
19 |
|
20 |
|
21 |
|
22 | export interface MacroableConstructorContract<T extends any> {
|
23 | macro<K extends string>(name: K, callback: GetMacroFn<T, K>): void;
|
24 | getter<K extends string>(name: K, callback: GetGetterFn<T, K>, singleton?: boolean): void;
|
25 | hydrate(): void;
|
26 | }
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | export declare abstract class Macroable {
|
37 | protected static macros: {
|
38 | [key: string]: MacroFn<any, any[], any>;
|
39 | };
|
40 | protected static getters: {
|
41 | [key: string]: GetterFn<any, any>;
|
42 | };
|
43 | constructor();
|
44 | /**
|
45 | * Add a macro to the class. This method is a better to manually adding
|
46 | * to `class.prototype.method`.
|
47 | *
|
48 | * Also macros added using `Macroable.macro` can be cleared anytime
|
49 | *
|
50 | * @example
|
51 | * ```js
|
52 | * Macroable.macro('getUsername', function () {
|
53 | * return 'virk'
|
54 | * })
|
55 | * ```
|
56 | */
|
57 | static macro<T extends any, K extends string>(this: {
|
58 | new (...args: any): T;
|
59 | }, name: string, callback: GetMacroFn<T, K>): void;
|
60 | /**
|
61 | * Return the existing macro or null if it doesn't exists
|
62 | */
|
63 | static getMacro(name: string): MacroFn<any, any[], any> | undefined;
|
64 | /**
|
65 | * Returns a boolean telling if a macro exists
|
66 | */
|
67 | static hasMacro(name: string): boolean;
|
68 | /**
|
69 | * Define a getter, which is invoked everytime the value is accessed. This method
|
70 | * also allows adding single getters, whose value is cached after first time
|
71 | *
|
72 | * @example
|
73 | * ```js
|
74 | * Macroable.getter('time', function () {
|
75 | * return new Date().getTime()
|
76 | * })
|
77 | *
|
78 | * console.log(new Macroable().time)
|
79 | *
|
80 | * // Singletons
|
81 | * Macroable.getter('time', function () {
|
82 | * return new Date().getTime()
|
83 | * }, true)
|
84 | *
|
85 | * console.log(new Macroable().time)
|
86 | * ```
|
87 | */
|
88 | static getter<T extends any, K extends string>(this: {
|
89 | new (...args: any): T;
|
90 | }, name: string, callback: GetGetterFn<T, K>, singleton?: boolean): void;
|
91 | /**
|
92 | * Return the existing getter or null if it doesn't exists
|
93 | */
|
94 | static getGetter(name: string): GetterFn<any, any> | undefined;
|
95 | /**
|
96 | * Returns a boolean telling if a getter exists
|
97 | */
|
98 | static hasGetter(name: string): boolean;
|
99 | /**
|
100 | * Cleanup getters and macros from the class
|
101 | */
|
102 | static hydrate(): void;
|
103 | }
|
104 | export {};
|