打字稿:如何将对象映射到类型?

Posted

技术标签:

【中文标题】打字稿:如何将对象映射到类型?【英文标题】: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 那么您介意删除标志吗? 我可以投票重新开放,就像我可以投票关闭一样。我会去做。您可以通过编辑来澄清您的问题,这会将问题置于重新打开队列中。 【参考方案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 的代码,以说明必须初始化而不仅仅是声明字段 感谢您的精彩解释!

以上是关于打字稿:如何将对象映射到类型?的主要内容,如果未能解决你的问题,请参考以下文章

打字稿不正确的分配/映射到强类型对象[关闭]

打字稿:如何根据对象键/值类型在 ES6 映射中创建条目

打字稿:如何制作接受对象的类型,其键匹配通用但所有值都是值参数的映射函数

“联合类型值到字符串的映射”的打字稿类型?

使用graphql代码生成器时如何将自定义标量类型映射到打字稿类型?

如何将方法的泛型类型限制为打字稿中的对象?