TypeScript:如何从另一个接口合并对象?

时间:2019-04-22 07:55:48

标签: typescript interface

我有以下界面:

interface TxInterface {
    field1: string;
    field2: string;
    field3: number;
}

interface RxInterface {
    field1: string;
    field2: string;
    field3: number;
    field4: string;
    field5: string;
}

当我从服务器收到一个对象时,将使用RxInterface键入该对象。在我的应用程序中,更新实例值时,我将继续使用该对象。

当我想更新服务器中的对象时,我将发送“ TxInterface”,其中包含“ RxInterface”的某些字段。

那么,如何在发送和仅接收TxInterface的字段之前轻松地将对象从RxInterface合并到TxInterface?

2 个答案:

答案 0 :(得分:1)

没有办法仅使用接口定义来执行此操作,因为此类定义是类型系统的一部分,类型系统在运行时为erased。如果您需要在运行时完成某项操作,则需要编写在运行时执行此操作的代码。在这种情况下,这是一个通用函数,该函数仅提取与键列表匹配的对象的属性:

function extract<T extends object, K extends keyof T>(
    obj: T,
    keys: K[]
): Pick<T, K> {
    const ret = {} as Pick<T, K>;
    keys.forEach(k => ret[k] = obj[k])
    return ret;
}

对于您的特定用例,您可以创建一个转换函数,其类型涉及RxInterfaceTxInterface,但是将您关心的特定键指定为值而不是类型:

const rxToTx = (rx: RxInterface): TxInterface => // type annotation here
    extract(rx, ["field1", "field2", "field3"]); // explicit key values here

您可以验证它是否有效:

const rx: RxInterface = {
    field1: "yes",
    field2: "yep",
    field3: 100,
    field4: "no",
    field5: "nope"
}

const tx = rxToTx(rx);

console.log(tx);
// {field1: "yes", field2: "yep", field3: 100}

希望有所帮助;祝你好运!

答案 1 :(得分:0)

好的。引入二进制运算(也称为“约简”)是一个很好的起点。

考虑通用函数签名:T -> T -> T。它的作用是接受两个相同类型T的参数,并以某种方式将它们“折叠”为一个相同类型T的单个结果实例。举一个简单的例子,在+上使用number或在string上串联。

事实证明,这样的二进制运算在数学的各个分支之间都是不可思议的,并且其建立理由远比编程方便得多。例如,“ semigroup”本质上是相同的二进制操作,几乎没有其他属性,在此不再赘述。

所以,不要忽略它。而是以一种可以利用上述(通用)签名的二进制操作的方式来设计代码。问题是:如何?映射!您是否听说过有关“映射/减少”方法的内容?这正是您要实现的:首先将一个不可约化的实例映射到一个可约化的实例,然后应用您拥有的约化之一来计算最终结果。

P.S。在您的情况下,映射很简单:只需明确指定通用参数,因为更宽的接口也可以满足更窄的接口。