【问题标题】:Clean way to map objects to other objects?将对象映射到其他对象的干净方法?
【发布时间】:2017-12-22 12:31:11
【问题描述】:

有没有将对象映射到其他对象的好方法?也欢迎图书馆推荐。

例如,假设我有这些类:

export class Draft {
    id: number;
    name: string;
    summary: string;
}

export class Book {
    id: number;
    name: string;
    info: Info;
}

export class Info {
    value: string;
}

传统上,要将字段从Draft 映射到Book,我必须为每个字段手动执行此操作:

export class Book {
    [...]

    fromDraft(Draft draft) {
        this.id = draft.id;
        this.name = draft.name;
        this.info = new Info();
        this.info.value = draft.summary;
    }
}

有没有更简单的方法来映射以相同方式命名的对象字段?例如DraftBookidname 字段,同时还能够定义自定义映射,例如从draft.summarybook.info.value

请注意,这与我的实际用例相差甚远。在这里,手动进行分配还不错,但是对于具有许多类似名称字段的对象来说,这是一件很麻烦的事情。

谢谢!

【问题讨论】:

  • 真的不知道你的问题是什么意思,但你能不能简单地将BookDraft 抽象成一个更通用的父类,共享公共字段,以及来自该父类的extend ?或者,您可以使用decorators
  • 这可能是一个选择,谢谢!

标签: typescript casting typing


【解决方案1】:

关于复制同名属性,可以使用Object.assign

fromDraft(Draft draft) {
    Object.assign(this, draft);
    this.info = new Info();
    this.info.value = draft.summary;
}

问题在于它也会创建this.summary,但它是一种复制属性的便捷方式,因此如果您可以对类进行不同的建模,那么您就可以使用它。

另一种选择是拥有一个共享属性名称列表,然后对其进行迭代:

const SHARED_NAMES = ["id", "name"];

fromDraft(Draft draft) {
    SHARED_NAMES.forEach(name => this[name] = draft[name]);
    this.info = new Info();
    this.info.value = draft.summary;
}

【讨论】:

    【解决方案2】:

    无论 TypeScript 是什么,您都可以使用 lodash _.mergeWith 并传递您的合并函数。

    优点:更通用(如果你有更多逻辑,你可以添加它(例如复杂类型)

    缺点:你需要lodash

    类似:

    var a = {
      foo: [1, 2, 3],
      bar: true
    }
    
    var b = {
      foo: [4, 5, 6, 7],
      bar: false
    }
    
    var c = _.mergeWith(a, b, function(a, b) {
      if (a.concat) {
        return a.concat(b);
      }
      else {
        return b;
      }
    })
    
    console.log('c', c);
    <script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>

    http://jsbin.com/xugujon/edit?html,js

    【讨论】:

    • 有趣的图书馆,谢谢!这实际上正是我想的那种映射器/合并!
    • 我的荣幸 :) 祝你好运!
    • 如何处理属性名称不同的情况? mergeWith 有办法处理吗?
    • @Dibzmania 我不确定我是否理解。您可以发布示例代码的链接吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 2019-05-27
    • 2014-11-07
    • 2012-07-18
    • 2022-11-24
    相关资源
    最近更新 更多