打字稿:无法推断类实例方法的已知返回类型

时间:2020-09-10 20:50:47

标签: typescript generics

我是泛型新手,试图创建泛型方法将普通的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)
    }
  }
}

(顺便说一句,这些泛型类型非常冗长-有没有办法将泛型存储为可重用类型?)

0 个答案:

没有答案