我是泛型新手,试图创建泛型方法将普通的Javascript对象“混合”为类实例,然后再次将其“脱水”为它们的原始普通对象类型。每个类都有一个.toObject()
方法,该方法返回的类型与构造函数中用于实例化的类型相同(请参见下面的MyClass
)。
我能够编写一个用于为普通对象进行水合的泛型函数,但是对于 de 水合而言,我无法弄清楚如何通用地引用.toObject()
方法的returntype(每个类都有此方法的其他返回类型)。
下面的代码中的第一个函数是我的脱水器,最后在.toObject
调用中使用它。如何更改此通用函数的类型,以便自动推断类型,而不必指定?
编辑:准备样品时,我一次编辑了太多东西。事实证明,将通用函数直接传递给.map()
不起作用,而编写箭头函数却有效。这是一个非常好的解决方案,尽管我很想知道为什么会这样,或者是否有使它起作用的技巧。
export function dehydrate<DehydratedObject,HydratedObject extends {toObject:()=>DehydratedObject}>(fancyObject:HydratedObject){
return fancyObject.toObject();
}
export function hydrate<DehydratedObject,TargetClass extends new (object:DehydratedObject)=>InstanceType<TargetClass>>(plainObject:DehydratedObject,targetClass:TargetClass){
return new targetClass(plainObject);
}
interface SourceData {
name: string,
children: SourceData[]
}
interface TransformedData extends Omit<SourceData,'children'>{
children: MyClass[]
}
class MyClass{
#data: TransformedData;
constructor(sourceData:SourceData){
this.#data = {
...sourceData,
// I do not need to specify classes when calling the 'hydrate' generic,
// which is perfect.
children: sourceData.children.map(child=>hydrate(child,MyClass))
};
}
toObject(): SourceData{
return {
...this.#data,
// QUESTION: This does not work, but if I replaced `dehydrate`
// with a full arrow function `child=>dehydrate(child)`
// it *does* work.
children: this.#data.children.map(dehydrate)
}
}
}
(顺便说一句,这些泛型类型非常冗长-有没有办法将泛型存储为可重用类型?)