By crafting a TypeScript class Decorator function, I have enabled the capability to adorn similar classes. Should a class find itself with a Decorator perched above it, said class will delve into the stored values of the Decorator for the highest priority class in its category. If the newly adorned class boasts a lower priority than the current highest priority class, it will be promoted to the status of that stored class.
In essence, all decorated classes within the same category should ultimately mirror the highest priority class.
For instance, envision having GeneralClassA (priority 0), SpecificClassA (priority 1) and ClassA (priority 0). All these classes ought to point towards a singular class, specifically, the SpecificClassA, owing to its superior priority level.
The strategy is to preset General classes with decorations while affording developers the freedom to define Specific classes and decorate them as higher priority entities.
While everything appears to function properly, there persists an issue where the decorated highest priority class must be declared PRIOR to any other decorated classes. Failing that sequence may lead to undecorated classes retaining precedence over previously designated classes.
Is there a method to retroactively supersede all decorated classes (by storing their constructors) once the higher priority class has been invoked and adorned? Or perhaps a means to ensure the declaration of all Specific classes precedes every other initialization?
I have reproduced my predicament here: StackBlitz
My attempt involved saving all decorated classes and attempting to merge one constructor and prototype to another once the high priority class was adorned. Unfortunately, this approach failed. Even if successful, what happens if the lower priority class had already been utilized prior to declaring the higher priority class (the actual class declaration transpires upon use during import).
I seek suggestions on initializing (declaring) all Specific classes preemptively, possibly even before the main.js file ever executes.
The specific decorator in question:
export const YIELD_LIST: {
[name: string]: { ctor: any; priority: number };
} = {};
type Constructable<T> = new (...args: any[]) => T;
export function Yield<T extends Constructable<any>>(
name: string,
priority: number = 0
) {
return (ctor: T) => {
if (!YIELD_LIST[name]) {
YIELD_LIST[name] = { ctor, priority };
} else {
if (YIELD_LIST[name].priority <= priority) {
YIELD_LIST[name] = { ctor, priority };
}
}
const maxPriorityCtor = YIELD_LIST[name].ctor as T;
return class extends maxPriorityCtor {
constructor(...args: any[]) {
super(...args);
}
};
};
}
Implementation example:
@Yield('CLASS_A', 1)
export class SpecificClassA extends GeneralClassA {
public override value = 10;
}