代码之家  ›  专栏  ›  技术社区  ›  Sergey Rudenko

typescript:如何键入一个对象,该对象有一个在实例化时不可用的必需字段?

  •  1
  • Sergey Rudenko  · 技术社区  · 6 年前

    所以我有一个“完整文档”对象的接口:

    export interface FullDocument {
        id: string,
        title: string,
        content: string,
        metadata: {
            author: string,
            createdAt: Date,
            updatedAt: Date
        }
        hash: Int32Array
    }
    

    在代码中,我希望通过var创建一个新的完整文档(假设我在没有类的情况下这样做,只需声明一个var,并且所有全局var都可用):

    var myNewDocument: FullDocument = {
        id: getUUID(),
        title: title,
        content: textArea,
        metadata: {
            author: author,
            createdAt: new Date(),
            updatedAt: new Date(),
        }
        hash: null
    }
    

    现在,我确实想在文档被实例化/创建之后对其进行哈希处理,因此最初我不能添加这样的哈希,因为它不可用(至少我认为是这样),因此我在后面这样做:

    myNewDocument.hash = hasherMethod(myNewDocument);
    

    所以问题是: 如果我有一个类型化的字段(这里是int32array),但在实例化期间不能在其中添加合法值,那么我可以选择只做“hash”?-将属性标记为可选的问号? 或者有一个传统的方法,这通常是怎么做的?

    我认为另一种方法可能是我区分类型并做到:

    • 未显示的完整文档类型
    • 哈希完整文档类型

    那么,打字机是如何做到的呢?

    4 回复  |  直到 6 年前
        1
  •  2
  •   Jonas Wilms    6 年前

    您使用typescript获得typesafety,因此您选择哪种方法取决于具体的用例:

     interface FullDocument {
       //...
       hash?: Int32Array;
     }
    

    这意味着 FullDocument 可能有哈希值,也可能没有。因此,每当您使用完整文档类型并希望访问 hash 你必须检查它是否已经存在。现在,如果您确实需要散列,您可以修复类型:

    const withHash: (FullDocument & { hash: Int32Array })[] = [];
    

    然后您必须检查每个插入中是否存在哈希。

        2
  •  3
  •   user9315861    6 年前

    这取决于细节,但是如果某个字段一次可能不在那里,然后在另一个时间可能在那里,则通常是设计不好的迹象(即使打印脚本帮助并教唆您使用 ? 符号)。

    问问你自己:这个土豆泥真的吗? 部分 文件的,还是 与关联 文件?如果后者是更准确的描述,那么您可能会考虑诸如 weakmap,由文档键控,保存哈希 --这种方法也可能有其他的优势。

    如果你不想花太多时间去思考文档的内在本质,并在“属于”和“关联”的概念之间画出细微的区别,那么只需选择一个字段即可。

    当然,另一种选择,同样取决于您的用例,是根据需要计算散列值,例如,如果散列值取决于文档的内容,并且该内容可能已经更改。说到这个,这个哈希是什么意思,它将被用来做什么?

        3
  •  2
  •   StriplingWarrior    6 年前

    我同意Torazaburo的观点,您所描述的情况使得散列听起来可能根本不应该是对象模型的一部分。

    我正在设想这样一种情况,即您有一个组件、服务或数据类型,它要求其所有“东西”都具有哈希属性,并且您正在考虑将此属性添加到您的模型中,以便能够将对象传递给它。

    在这种情况下,我将考虑使用组合:您可以创建一个新的、具有两个属性的泛型类型:一个对象及其哈希。此类型的对象可用于提供哈希,而不修改其他类型,因此遵循打开/关闭原则。

        4
  •  0
  •   webnetweaver    6 年前

    只需在实例化时将其设置为空或未定义。除非设置了strictnullchecks标志,否则所有类型都可以指定为空和未定义。