我有以下界面:
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?
答案 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;
}
对于您的特定用例,您可以创建一个转换函数,其类型涉及RxInterface
和TxInterface
,但是将您关心的特定键指定为值而不是类型:
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。在您的情况下,映射很简单:只需明确指定通用参数,因为更宽的接口也可以满足更窄的接口。