typescript - TypeScript 与数组的交集
问题描述
我正在使用 lodashmerge
合并两个对象。lodash 的类型(https://github.com/DefinitelyTyped/DefinitelyTyped/blob/bab9c9aef2477d222f014a25ce86585af76c3a5c/types/lodash/common/object.d.ts#L1718)仅依赖于在数组方面有一些缺点的交集类型。
假设我想合并具有这些类型的对象
interface One {
str: string;
arr: Array<{ foo: string }>;
}
interface Two {
num: number;
arr: Array<{ bar: string }>;
}
当这些对象与 lodash 合并时merge
,生成的形状是
interface Merged {
str: string;
num: number;
arr: Array<{ foo: string; bar: string }>;
}
但这不是交集类型的工作方式(这里的基本原理)。你最终得到的类型arr
是Array<{ foo: string; }> & Array<{ bar: string }>
有这个问题:
declare const test: Array<{ foo: string }> & Array<{ bar: string }>;
test.forEach((item) => item.bar); // Property 'bar' does not exist on type '{ foo: string; }'.(2339)
可以为数组merge
定义更好的Array<A>
类型Array<B>
吗?它必须是某种递归映射类型,但我没有任何运气写一个。Array<A & B>
Array<A> & Array<B>
解决方案
我认为我们可以创建一种递归地规范化数组的类型。
type NomalizeArrays<T> = {
[P in keyof T]: T[P] extends any[] ? Array<NomalizeArrays<T[P][number]>> : NomalizeArrays<T[P]>
}
我们可以通过 中的任何路口T
。除了数组,我们大多不考虑结构。对于数组,我们T[P][number]
将其作为对象类型的交集。
它似乎无法按预期工作,如果您发现任何问题,请告诉我:
let r = _.merge({
arr: [{ foo : "A"}],
str: ""
}, {
arr: [{ bar: "B"}],
num: 1
})
r.arr.forEach(x => x.bar + x.foo);
let r2 = _.merge({
arr: [{ outerA: "", nested: [{ foo: "" }]}]
}, {
arr: [{ outerB: "", nested: [{ bar: "" }]}]
})
r2.arr.forEach(x => {
x.outerA
x.outerB
x.nested.map(xx => xx.bar + xx.foo)
});
推荐阅读
- python-3.7 - 为什么表格不适用于数字 10、11 和 12?
- mule - 如何定义 RAML 规范以接受遵循特定路径的所有 URI 参数
- css - Bootstrap 4 - 容器填充整个屏幕,滚动后显示页脚
- git - Invoke-Expression,并非所有输出都返回到变量
- amazon-web-services - 如何一起使用 Fn::Include 和 Fn::Sub?
- c - 将联合传递给函数无法识别参数名称
- java - 在控制器方法签名处处理异常
- javascript - 页面重新加载后如何使代码在已挂载的生命周期挂钩中运行
- java - Spring Boot 不需要 CSRF 令牌
- flutter - 将小部件的底部动态设置到另一个小部件的中间