创建对象副本的函数支持操作

Function-Backed Action which creates a duplicates of an Object

是否可以编写一个 TypeScript 函数,以编程方式创建对象的副本,而无需对要复制的对象属性进行硬编码引用?

我正在尝试启用一个用户工作流程,在该工作流程中,用户有权创建指定对象的副本,即使用表单创建并部分完成一个对象,创建新对象的 10 倍副本,填写数据对于新对象。

我已经成功地创建了一个复制指定对象的函数支持的操作,但是对被复制的属性的所有引用都是硬编码的,这对于维护来说不太理想,并且是我们组织的一个相对常见的请求。

所需函数的代码示例:

@OntologyEditFunction()
public GenerticBatchCopyObjects(mySelectedObject: ObjectAPIName, numberNewObjects: Integer): void {
    /** Set UUID primary key */
    let object_pk = Uuid.random()

    for (let i = 1; i <= numberNewObjects; i++) {
        /** initialize new object */
        const newObject = Objects.create().ObjectAPIName(object_pk + "_" + String(i))

        /** copy all properties from selected object record to new object */
        for property in mySelectedObject.properties:
            if property != "name_of_primary_key_column":
                newObject.property = mySelectedObject.property 
    }
}

目前并没有很好的方法来实现这一点,可能不建议这样做。这主要是因为将从对象复制的属性列表在我能看到的任何(好的)方法中固定在 publish-/compile-time。

仅复制属性的部分type-safe解决方案

我在下面包含了我可以构建的此函数的最通用版本,但它有一些限制。更具体地说,copy 函数

  1. 不复制 FK 属性未表示的链接(即仅复制属性);
  2. 不适应,当有新的或删除的属性时可能会中断;和
  3. 不容易维护,因为功能会根据编译时间而改变。
private isPrimaryKey(x: string): x is MyObjectType["primaryKey"]["apiName"] {
    return x === MyObjectType.primaryKey.apiName;
}

@OntologyEditFunction()
public copy(obj: MyObjectType): void {
    const new_obj = Objects.create().myObjectType(Uuid.random());
    var prop : keyof typeof MyObjectType.properties;
    for (prop in MyObjectType.properties) {
        if (!this.isPrimaryKey(prop)) {
            new_obj[prop] = obj[prop];
        }
    }
}

复制所有内容的显式type-safe解决方案

如果 ontology 更改,下面的方法需要更多的手动调整,但明确表示代码必须根据 ontology 更改进行更改。这种方法也会复制链接。

还值得注意的是,此行为可能不是期望的行为,因为它不会递归复制链接对象,而是尝试 复制链接。请测试这是否会产生所需的结果。

static PROPERTIES = ["myProperty"] as const;
static MULTILINKS = ["myMultiLink"] as const;
static SINGLELINKS = ["mySingleLink", "myOtherSingleLink"] as const;

@OntologyEditFunction()
public copy2(obj: MyObjectType): void {
    const new_obj = Objects.create().myObjectType(Uuid.random());
    MyFunctions.PROPERTIES.forEach(p => {
        new_obj[p] = obj[p];
    });
    MyFunctions.MULTILINKS.forEach(p => {
        obj[p].all().forEach(v => new_obj[p].add(v));
    });
    MyFunctions.SINGLELINKS.forEach(p => {
        const v = obj[p].get();
        if (v !== undefined) {
            new_obj[p].set(v);
        }
    });
}

如果您的对象类型没有 properties/multi-links/single-links 以使编译器满意,您可能需要排除一些代码。