我想Map第一个obj的所有对象值,并保留Wrapped对象的泛型类型。
我尝试过使用Map类型,但它在两个方面失败了:
1.我无法在MapToWrappedType中表示嵌套对象
1.无法确定如何表示类型,因此Map的类型不是Wrapper<ValueObject<...>>
而是Wrapper<...>
出发地:
{
a: ValueObject<number>,
b: ValueObject<number>,
c: {
d: ValueObject<string>,
e: ValueObject<number>
}
}
收件人:
{
a: Wrapper<number>,
b: Wrapper<number>,
c: {
d: Wrapper<string>,
e: Wrapper<number>
}
}
class ValueObject<T> {
public value: T;
constructor(value: T) {
this.value = value;
}
}
class Wrapper<T> {
public value: T;
constructor(vo: ValueObject<T>) {
this.value = vo.value;
}
}
const obj = {
a: new ValueObject<number>(1),
b: new ValueObject<number>(2),
c: {
d: new ValueObject<string>("3"),
e: new ValueObject<number>(4)
}
} as const;
// 2 Problems:
// - how to express a nested object?
// - how to change the type to Wrapper<...> instead of Wrapper<Valueobject<...>>?
type MapToWrapped<T> = {
[K in keyof T]: Wrapper<T[K]>
}
function toWrappedObj<T>(obj: T): MapToWrapped<T> {
const result: any = {};
for (const key in obj) {
const item = obj[key];
if (item instanceof ValueObject) {
result[key] = new Wrapper<any>(item.value);
} else {
result[key] = toWrappedObj(item);
}
}
return result;
}
const wrappedValuesObj = toWrappedObj(obj);
const x = wrappedValuesObj.a // should be Wrapper<number>
1条答案
按热度按时间xpcnnkqh1#
我们需要使用mapped types和inferor关键字来删除
ValueObject
,并将其替换为Wrapper
。来自docs的
infer
示例:因此本例检索数组项的类型;我们可以使用相同的方法,但使用
ValueObject
。然后我们可以将
Item
Package 在Wrapper
中以获得预期的结果。对于更深的层次,如果mapped属性不是
ValueObject
,我们将递归调用我们的mapper类型,假设不能嵌套ValueObject
。此外,为了使结果类型更具可读性,我们将使用Prettify
实用程序类型:使用方法:
Playground