【问题标题】:Typescript: How to map object to type?打字稿:如何将对象映射到类型?
【发布时间】:2018-06-18 09:32:18
【问题描述】:

假设我有一个包含一些数据的对象。我想为所有类型构建一个通用映射器(分别只有一个函数 - 我不想一直实例化一个新类),以便像这样使用:this.responseMapper.map<CommentDTO>(data);

它应该简单地从给定类型中获取所有属性并将数据映射到它。 到目前为止我尝试了什么:

public map<T>(values: any): T {
    const instance = new T();

    return Object.keys(instance).reduce((acc, key) => {
        acc[key] = values[key];
        return acc;
    }, {}) as T;
}

new T(); 会抛出错误:'T' only refers to a type, but is being used as a value here.

这样做的正确方法是什么?

【问题讨论】:

  • 如果添加参数type: typeof T,并调用new type(),是否编译?
  • 不,它没有,不,这不是真正的重复,因为我不想一直实例化新的映射器类。
  • 我明白了,感谢您的澄清。措辞使它看起来正是您想要做的。如果你只是想过滤掉不属于类型键的键,一些函数库会调用这个操作pick
  • 那么您介意删除标志吗?
  • 我可以投票重新开放,就像我可以投票关闭一样。我会去做。您可以通过编辑来澄清您的问题,这会将问题置于重新打开队列中。

标签: javascript class typescript object mapping


【解决方案1】:

您需要将类型构造函数传递给方法。 Typescript 在运行时将泛型擦除到 T 在运行时未知。另外,我会收紧values bti,只允许传入T 的成员。这可以通过Partial&lt;T&gt; 来完成

public map<T>(values: Partial<T>, ctor: new () => T): T {
    const instance = new ctor();

    return Object.keys(instance).reduce((acc, key) => {
        acc[key] = values[key];
        return acc;
    }, {}) as T;
 }

用法:

class Data {
    x: number = 0; // If we don't initialize the function will not work as keys will not return x
}

mapper.map({ x: 0 }, Data)

【讨论】:

  • 这是有道理的——如果我登录instance,我看不到它的任何属性吗? `new () => T` 语法是如何工作的?该主题的任何文档?
  • 这一切都取决于该类是如何定义的。如果您只是声明属性,则在分配它们之前您将不会在运行时看到任何值。 new ()=&gt; T 是构造函数签名,将执行类的构造函数。在上面的例子中,taht 相当于说new Data()
  • 编辑了初始化 x 的代码,以说明必须初始化而不仅仅是声明字段
  • 感谢您的精彩解释!
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 2019-04-11
  • 2019-11-19
  • 2022-12-23
  • 2021-04-02
  • 2021-01-26
  • 2022-12-07
  • 1970-01-01
相关资源
最近更新 更多