This repository has been archived by the owner on Sep 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
amend-member-of.ts
47 lines (45 loc) · 1.56 KB
/
amend-member-of.ts
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
import { Amendment } from '../base';
import { AmendableClass } from '../class';
import { AeMember, DecoratedAeMember } from './ae-member';
/**
* Amends a member (property) of the class.
*
* Applies the given amendments to the own property of the target class prototype.
*
* @typeParam TClass - A type of amended class.
* @typeParam TKey - A type of amended member key.
* @typeParam TAmended - A type of the entity representing a member to amend.
* @param decorated - Decorated class representation.
* @param memberKey - A key of the member to amend.
* @param amendments - Amendment to apply.
*/
export function amendMemberOf<
TClass extends AmendableClass,
TKey extends keyof InstanceType<TClass> = keyof InstanceType<TClass>,
TAmended extends AeMember<InstanceType<TClass>[TKey], TClass> = AeMember<
InstanceType<TClass>[TKey],
TClass
>,
>(
decorated: DecoratedAeMember<TClass, TAmended>,
memberKey: TKey,
...amendments: Amendment<TAmended>[]
): void {
const amendment = AeMember<
InstanceType<TClass>[TKey],
TClass,
InstanceType<TClass>[TKey],
TAmended
>(...amendments);
const proto: object = decorated.amendedClass.prototype;
const sourceDesc = Reflect.getOwnPropertyDescriptor(proto, memberKey);
const amendedDesc = amendment.decorateAmended(
decorated as DecoratedAeMember<TClass, TAmended & AeMember<InstanceType<TClass>[TKey], TClass>>,
memberKey as string | symbol,
sourceDesc,
);
if (amendedDesc && sourceDesc) {
// Redefine the property.
Reflect.defineProperty(proto, memberKey, amendedDesc);
}
}