I get a circular dependency on my decorators because my class ThingA
has a relation with ThingB
and vice versa. I've read several questions about this issue:
But I wasn't able to find a valid solution for my case. I tried as many people suggest to change from @hasOne(ThingA)
to @hasOne(() => ThingA)
to force a lazy loading and break the dependency, but this solution doesn't work because I'm not able to get the constructor name. I need the name of the constructor (example: 'ThingA') to add it in metadata of constructor ThingB.
Following my original code (without lazyload modification)
ThingA
@hasAtLeast(0, ThingB)
export class ThingA extends RTContent {
@IsEmail()
email: string;
}
ThingB
@hasOne(ThingA)
export class ThingB extends RTContent {
@IsString()
description: string;
}
Decorators:
export type LinkConstraint<C extends RTContent> = {
content: string; // name of the constructor (ex. 'ThingA')
maxOccurrences: number;
minOccurrences: number;
constructor: { new(...args: any[]): C };
}
function constraintFactory<C extends RTContent>(minOccurrences: number, maxOccurrences: number, associated: { new(...args: any[]): C }) {
return (constructor: Function) => {
const constraints = Reflect.getMetadata('linkConstraints', constructor) || [];
const constraint: LinkConstraint<C> = {
content: associated?.name,
minOccurrences,
maxOccurrences,
constructor: associated
};
constraints.push(constraint);
Reflect.defineMetadata('linkConstraints', constraints, constructor)
}
}
export function hasOne<C extends RTContent>(associated: { new(...args: any[]): C }) {
return constraintFactory(1, 1, associated)
}
export function hasAtLeast<C extends RTContent>(minOccurrences: number, associated: { new(...args: any[]): C }) {
return constraintFactory(minOccurrences, Infinity, associated)
}
from Typescript - Circular dependency on decorator
No comments:
Post a Comment