【发布时间】:2020-07-31 12:21:45
【问题描述】:
我想编写一个函数,用另一个对象扩展一个对象。例如:我们将调用一个对象src 和另一个ext。该函数必须返回(一个副本)src 对象,但深度(递归地)使用ext 对象扩展该对象。如果ext 的一个(子)属性的数据类型与src(子)属性的类型不匹配,则函数必须忽略ext 值。 ext 中的新属性(src 中不存在)将添加到结果对象中。
为了更好地理解这里一个完整的例子:
/** A helper definition to build indexable objects */
interface indexObject<T> {
[key: string]: T
}
type SafelyMergedObject<Src extends indexObject<any>, Ext extends indexObject<any>> = {
// The searched type definition
}
const src= {
a: "a",
b: "b",
c: false,
d: {
a: "Alice",
b: "Bob",
}
}
const ext = {
a: ["a"],
b: 1,
c: true,
d: {
a: "Ann",
c: "Clair",
},
e: "New value",
}
const result: SafelyMergedObject<typeof src, typeof ext> = {
a: "a", /** Only string should be allowed here because
it's the property type of the source (Src) type */
b: "b", /** Same as above (`a` property) */
c: true,/** Since `c` has the same data type the function
should return the property value of the `ext`
object */
d: { /** Same data type in both objects */
a: "Ann", /** new value from `ext` */
b: "Bob", /** copied value from `src` */
c: "Clair", /** new property from `ext` */
},
e: "New Value", /** new property from `ext` */
}
我知道如何编写函数。这很容易,但我不知道如何编写这种类型定义。这可能吗?
默认的 TypeScript 类型推断行为不适合我的问题,因为类型是递归的,并且比简单的 object 类型更复杂。例如,我将使用该功能将用户特定的配置加载到我的应用程序中。用户配置可能已损坏。所以我必须将默认配置与用户特定配置合并。
【问题讨论】:
-
看看你的函数会很好(因为你知道如何编写它)而且通常编译器会正确推断出返回类型,所以这通常不是棘手的部分。从您的示例中不清楚您期望的输出是什么,因为 bot
src和ext共享相同的道具名称a -
@DamianGreen 感谢您的回复。我希望最后的编辑可以帮助您理解我的问题。提到的功能取决于许多其他代码。在发布之前,我必须大大缩短代码。但也许这个编辑已经有所帮助。如果没有,请告诉我。
-
SafelyMergedObject是一个函数吗?这是它的一个对象 -
@DamianGreen SafelyMergedObject 类型应该是描述合并对象的泛型类型。
-
您是否正在寻找this?如果源属性类型存在,您似乎总是使用它,但如果没有更多用例,就很难判断。您可以尝试链接类型并查看它是否有效或中断,然后更新您的问题吗?如果可行,我会写下来。
标签: typescript types