【问题标题】:Can this circular dependency in TypeScript be refactored so separate TypeScript files are possible?可以重构 TypeScript 中的这种循环依赖,以便可以使用单独的 TypeScript 文件吗?
【发布时间】:2016-12-31 20:13:57
【问题描述】:

我在同一个 .ts 文件中有那些 TypeScript 类,因为存在导入依赖项。如果有人可以帮助我重构代码,我将不胜感激,以便我可以删除导入的循环引用:

第一个是摘要GenericModel

export abstract class GenericModel {
    nodeClass: string;
    id: string = "0";

    static fromJson(json: any): GenericModel {
        if (json.nodeClass === "Entity") {
            return EntityModel.fromJson(json);
        }
        else if(json.nodeClass === "User") {
            return UserModel.fromJson(json);
        }
        return null;
    }
}

另外两个类是EntityModel(如下所列)和UserModel

export class EntityModel extends GenericModel {
    nodeClass: string = "Entity";
    alias: string;
    description: string;

    constructor(public text: string, public id: string, public uuid: string, alias: string, public rand:string = "") {
       //[...]
    }

    //instance methods
    //[...]

    public static fromJson(json: any): EntityModel {
        var entity = new EntityModel(json.text, json.id, json.uuid, json.alias, json.rand);
        entity.description = json.description;

        if (json.types) {
            for (let type of json.types) {
                let objectifiedType: EntityModel = EntityModel.fromJson(type);
                entity.types.push(objectifiedType);
            }
        }
        if (json.innerEntities){
            for (let innerEntity of json.innerEntities) {
                let objectifiedInnerEntity: EntityModel = EntityModel.fromJson(innerEntity);
                entity.innerEntities.push(innerEntity);
            }
        }
        return entity;
    }
}

我在这里所做的是使用基于nodeClass 的静态调用fromJson() 的层次结构对JSON 进行反序列化。

很明显,如果GenericModel 在单独的文件中,则需要导入EntityModelUserModel 而另外两个如果它们在单独的文件中,则需要导入GenericModel

GenericModel --- has to import --> EntityModel, UserModel

EntityModel --- has to import --> GenericModel

UserModel --- has to import --> GenericModel

我想知道是否有一种方法可以重构代码,使其能够实现现在的功能,而且这些类位于单独的 .ts 文件中。

谢谢!

【问题讨论】:

    标签: typescript circular-dependency circular-reference


    【解决方案1】:

    这里的技巧是将循环依赖项隔离到它们自己的模块中。我会将所有fromJson 方法提取到一个单独的新模块中。然后我会将fromJson 转换成一个类似于ModelFactory 的类,因为这现在更类似于工厂模式。因此,最终结果将如下所示:

    export class ModelFactory {
      // maybe add a constructor for some configuration data, maybe not
    
      create(json: any) {
        ...
      } 
    }
    

    现在,我还看到您将json 对象键入为any。当您似乎至少知道该类型的一些属性时,这似乎有点宽泛。我会尝试为 json 对象创建一个接口,如下所示:

    export interface ModelJson { // find a better name
      text?: string; 
      id?: number;
      uuid?: UUID; 
      alias?: string;
      rand?: number;
      ...
    }
    
    type UUID = number;
    

    这是一种更具打字性的做事方式。

    【讨论】:

    • 谢谢!我觉得我需要像你建议的工厂一样添加一个新类!感谢界面/json 的提示 :) 顺便说一句,最后type UUID = number; 是什么?新年快乐!
    • 这只是一个类型别名。当你有类似 UID 的东西恰好是一个数字,但实际上它只是一个技术细节并且它有自己的语义时,你经常使用类型别名。这可确保您只能在预期的情况下使用 UID,并且不会意外传入普通数字。
    • 对我来说,uuid 是一个字符串!我还能做吗:type UUID = string;?谢谢
    • 当然。有关类型别名的更多信息,请参见:typescriptlang.org/docs/handbook/advanced-types.html 通常,我主要使用类型别名来更好地记录参数和属性。它们从来都不是应用程序的基础。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2019-03-19
    • 2019-12-09
    • 2022-11-12
    相关资源
    最近更新 更多