【问题标题】:Circular reference using dependency inversion issue使用依赖倒置问题的循环引用
【发布时间】:2023-01-18 18:11:07
【问题描述】:

我有一个使用这种模式方法的循环引用问题。 TypeError: Class extends value undefined is not a constructor or null

奇怪的是,如果我在src/constants.ts 中移动field.type.ts,它不会抛出错误并且按预期工作,但在单元测试时崩溃。如果它将 fied.type.ts 内容留在它自己的文件中,它就会崩溃。

也许我没有以正确的方式使用/理解这种依赖倒置模式。我可能可以通过将 FieldTypeToClassMapping 作为参数传递给 Field.create(options: FieldOptions, fieldTypeMapping: FieldTypeToClassMapping) 来修复,但我想了解为什么会这样。

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;

【问题讨论】:

  • 让每个子类在FieldTypeToClassMapping 中注册自己,而不是在声明父类的同一模块中导入所有子类。
  • 是的,这是一个循环模块依赖问题,所以请edit你的问题在你的代码中显示模块import语句
  • 您使用的是哪个模块系统?你将 TypeScript 编译成 ES6 模块还是 CommonJS?

标签: javascript typescript design-patterns es6-modules circular-dependency


【解决方案1】:

create(options: FieldOptions) 函数在类Field 中定义,但随后它会尝试实例化扩展Field 的类的实例。

我认为这就是问题所在。我不知道你文件的全部内容,但我想在你导入Field 的任何field.type.ts 文件的顶部。但是,由于Field 可以实例化其自身的任何具体实现,因此它需要了解它们,因此您需要导入在Field 中扩展Field 的所有内容。

我不太了解/理解依赖倒置模式,无法将其与您的问题联系起来。但鉴于提供的信息,也许工厂模式是你需要的吗?

您可以将函数 create(options: FieldOptions) 移动到 FieldFactory 类。您的创建功能实际上已经是一个工厂功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多