Monday 28 September 2020

Typescript - Circular dependency on decorator

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