mercredi 18 janvier 2023

Circular reference using dependency inversion issue

I have a circular reference issue using this pattern approach. TypeError: Class extends value undefined is not a constructor or null .

The strange thing is, if I move the field.type.ts in src/constants.ts, it doesn't throw an error and it works as expected, but crashes on the Unit Tests. If it leave the fied.type.ts contents in it's own file, it crashes.

Maybe I am not using/understanding this dependency inversion pattern the right way. I could probably fixed by passing the FieldTypeToClassMapping as a parameter in Field.create(options: FieldOptions, fieldTypeMapping: FieldTypeToClassMapping), but I want to understand why this is happening.

export const FieldTypeToClassMapping = {
  //Constructor of eg. StringField class so I can use `new FieldTypeToClassMapping[options.type](options)`;
  [FieldTypeEnum.STRING]: StringField,
  [FieldTypeEnum.INTEGER]: IntegerField,
};
//field/field.ts
export abstract class Field {
  value: any;
  type: string;

  errors: string[] = [];

  public constructor(options: FieldOptions) {
    this.value = options.value;
    this.type = options.type;
  }

  public static create(options: FieldOptions): any {
    try {
      return new FieldTypeToClassMapping[options.type](options);
    } catch (e) {
      throw new Error(`Invalid field type: ${options.type}`);
    }
  }
}
//field/integer.field.ts
export class IntegerField extends Field {
  constructor(options: FieldOptions) {
    super(options);
  }
  protected validateValueDataType() {
    this.validateDataType(this.value, "value");
  }

  protected validateDefaultDataType() {
    this.validateDataType(this.defaultValue, "defaultValue");
  }
}
//field/service.ts
payload const postFields = [
  {
    type: "string", //FieldTypeEnum.STRING,
    value: 'a name'
  },
];

const postFields = [
  {
    type: "string",
    value: "John",
  },
  {
    type: "integer",
    value: 32,
  },
];


const fieldsArray = [];
postFields.forEach((item) => {
    const field: Field = Field.create(item);
    fieldsArray.addField(field);
  });

return fieldsArray;

Aucun commentaire:

Enregistrer un commentaire