Repository navigation
Expand file tree
/
Copy pathInitializable.ts
More file actions
58 lines (44 loc) · 2.15 KB
/
Copy pathInitializable.ts
File metadata and controls
58 lines (44 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/* tslint:disable:no-invalid-this */
import { IInitializable } from '../interfaces/IInitializable';
/**
* @param initializeMethodKey
* @returns {(target:IInitializable, propertyKey:(string|symbol))=>PropertyDescriptor}
*/
export function initializable (
initializeMethodKey: string = 'initialize'
): (target: IInitializable, propertyKey: string | symbol) => any {
const decoratorName: string = Object.keys(this)[0];
return (target: IInitializable, propertyKey: string | symbol): any => {
const initializeMethod: any = (<any>target)[initializeMethodKey];
if (!initializeMethod || typeof initializeMethod !== 'function') {
throw new Error(`\`${initializeMethodKey}\` method with initialization logic not found. \`@${decoratorName}\` decorator requires \`${initializeMethodKey}\` method`);
}
const methodDescriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor(target, initializeMethodKey) || {
configurable: true,
enumerable: true
};
const originalMethod: Function = methodDescriptor.value;
methodDescriptor.value = function (): void {
originalMethod.apply(this, arguments);
// call property getter to activate initialization check inside it
if (this[propertyKey]) {}
};
Object.defineProperty(target, initializeMethodKey, methodDescriptor);
const metadataPropertyKey: string = `_${propertyKey}`;
const propertyDescriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor(target, metadataPropertyKey) || {
configurable: true,
enumerable: true
};
propertyDescriptor.get = function(): any {
if (this[metadataPropertyKey] === undefined) {
throw new Error(`Property \`${propertyKey}\` is not initialized! Initialize it first!`);
}
return this[metadataPropertyKey];
};
propertyDescriptor.set = function (newVal: any): void {
this[metadataPropertyKey] = newVal;
};
Object.defineProperty(target, propertyKey, propertyDescriptor);
return propertyDescriptor;
};
}