返回具体类构造函数的函数的类型声明

时间:2018-09-28 08:41:34

标签: typescript

考虑以下代码:

abstract class AbstractFoo {
} 

class Foo extends AbstractFoo {
}

class Bar {
    getFooConstructor(): typeof AbstractFoo {
       return Foo;
    }
}

let bar = new Bar();
let FooConstructor = bar.getFooConstructor();
let foo = new FooConstructor();

它无法编译并出现以下错误:

  

错误TS2511:无法创建抽象类的实例。

这并不意外,因为getFooConstructor被声明为返回AbstractFoo构造函数-即抽象构造函数。

如何键入getFooConstructor返回值,以便TypeScript编译器理解它返回扩展了AbstractFoo的具体构造函数?

1 个答案:

答案 0 :(得分:1)

问题在于打字稿会在类的类型(即typeof AbstractClass)中记住构造函数是抽象类,因此无法调用。

最简单的解决方案是改用构造函数签名:

abstract class AbstractFoo {
} 

class Foo extends AbstractFoo {
}

class Bar {
    getFooConstructor(): new ()=> AbstractFoo {
      return Foo;
    }
}

let bar = new Bar();
let FooConstructor = bar.getFooConstructor();
let foo = new FooConstructor();

虽然这可行,但如果您还需要访问类的静态成员,则不能这样做({getFooConstructor返回一个构造函数,该构造函数返回从AbstractFoo派生的东西,而不是实际的类本身)。如果您从抽象类类型派生接口,则可以实现此目的,这将消除构造函数的抽象性,并使我们既可以调用构造函数,又可以访问所有静态成员:

abstract class AbstractFoo {
  static m(): void { }
}
type AbstarctFooClass = typeof AbstractFoo;
interface AbstractFooDerived extends AbstarctFooClass { }

class Foo extends AbstractFoo {
}

class Bar {
  getFooConstructor(): AbstractFooDerived {
    return Foo;
  }
}

let bar = new Bar();
let FooConstructor = bar.getFooConstructor();
FooConstructor.m()
let foo = new FooConstructor();
相关问题