【问题标题】:Typeof typescript class is not assignable to that of a class which extends itTypeof typescript 类不能分配给扩展它的类
【发布时间】:2019-07-09 01:46:19
【问题描述】:

我们有一个基础StoreObject 类,它为保存到数据库的对象提供转换/清理等通用方法。我希望能够使用泛型从这些方法中指定更严格的返回类型。但是,在将typeof StoreObjecttypeof AClassThatExtendsStoreObject 进行比较时,我的尝试导致错误,这是我们在各种实用函数中所做的检查。你能指出我在下面做错的方向吗?


class StoreObject<S> {
  toStoreObject(s: S): S {
    // Perform some sanitisation etc.
    return s;
  }
}

interface Fact {
  id: string;
  fact: string;
}

// A concrete implementation of StoreUnit where we attempt to define the actual model of the object being stored
class FactStoreObject extends StoreObject<Fact> {}

// We've got some general utils that interact objects using these classes 
// These typicallay take a concrete implementation of StoreUnit to be used as a parser/processer
function doSomething(StoreObjectClass: typeof StoreObject) {
  // Typically:
  // const parsedObject = new StoreObjectClass(someObject).toStoreObject()
  // persistToDb(parsedObject)
}

// This errors with "Type 'S' is not assignable to type 'Fact'"
doSomething(FactStoreObject);

playground link

【问题讨论】:

  • 你不能让doSomething() 通用吗? FactStoreObject 不能创建通用的 StoreObject&lt;S&gt; 实例...它只能创建 StoreObject&lt;Fact&gt; 实例。

标签: typescript typescript-typings typescript-generics


【解决方案1】:

错误是由于这一行:

const parsedObject = new StoreObjectClass(someObject)

首先,你需要可构造的接口:

export interface IConstructable<T> {
    new (): T;
}

其次,您需要将类型的参数包含在您的工厂方法中:

function doSomething<T>( t: IConstructable<T> ) {
  const parsedObject = ( new t() ).toStoreObject();
  // persistToDb(parsedObject);
}

【讨论】:

  • 尽管我们都得到了基本相同的解决方案,但我想认识到将接口用于构造函数签名是一种优雅的接触
【解决方案2】:

在提供的代码中,在“doSomething”函数中,参数类型被指定为“StoreObject”,而没有指定的泛型类型。为了修复错误,您需要执行以下操作:

  1. 将“StoreObject”的通用参数(本例中为Fact)传递给doSomthing

  2. doSomething 函数的参数必须指定一个带有构造函数签名的类型,该签名允许创建一个新实例。

    示例如下:

function doSomething<T>(StoreObjectClass: { new(): StoreObject<T> }) {
  // typically
  const someObject = <any>{id: "001", fact: "A real fact"};
  const parsedObject = new StoreObjectClass().toStoreObject(someObject);
  // persistToDb(parsedObject)
}

doSomething<Fact>(FactStoreObject);

【讨论】:

    猜你喜欢
    • 2020-07-14
    • 2021-05-15
    • 1970-01-01
    • 2022-01-22
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-27
    相关资源
    最近更新 更多