TypeScript中的抽象构造函数类型

时间:2016-04-27 09:44:12

标签: constructor typescript abstract-class

TypeScript中非抽象类(非抽象构造函数)的类型签名如下:

declare type ConstructorFunction = new (...args: any[]) => any;

这也称为 newable 类型。但是,我需要一个 abstract 类的类型签名(抽象构造函数)。我知道它可以被定义为类型为Function,但方式过于宽泛。难道没有更精确的替代方案吗?

修改

为了澄清我的意思,下面的小片段演示了抽象构造函数和非抽象构造函数之间的区别:

declare type ConstructorFunction = new (...args: any[]) => any;

abstract class Utilities {
    ...
}

var UtilityClass: ConstructorFunction = Utilities; // Error.
  

Type' typeof Utilities'不能分配给' new(... args:any [])=>任何'

     
    

无法将抽象构造函数类型分配给非抽象构造函数类型。

  

6 个答案:

答案 0 :(得分:26)

我自己正在努力解决类似的问题,这似乎对我有用:

type Constructor<T> = Function & { prototype: T }

答案 1 :(得分:3)

遇到同样的问题。我想,抽象类构造函数签名的本质是它的声明中new ( ... ) : X thingy的 absense 。这就是为什么它可以明确声明。

然而。你可以这样做,它会编译。

var UtilityClass: typeof Utilities  = Utilities;

typeof Something是一种引用构造函数类型的好方法,但是它无法扩展。

无论如何你可以这样做:

var UtilityClass: ConstructorFunction = <any> Utilities;

答案 2 :(得分:1)

从 TypeScript 4.2 开始,您可以使用 abstract constructor type

abstract class Utilities {
    abstract doSomething(): void;
}

type ConstructorFunction = abstract new (...args: any[]) => any;
var UtilityClass: ConstructorFunction = Utilities; // ok!

答案 3 :(得分:0)

抽象类(一般来说是OO)的重点是你不能实例化它们,你需要一个具体的非抽象实现。

我假设您希望对该抽象类有不同的实现,并希望能够接收其中一个实现(作为参数或类似的东西)。
如果是这样,那么这可能会解决您的问题:

declare type ConstructorFunction<T extends Utilities> = new (...args: any[]) => T;

abstract class Utilities { }

class MyUtilities extends Utilities { }

var UtilityClass: ConstructorFunction<MyUtilities> = MyUtilities; 

答案 4 :(得分:0)

此解决方案:


Dim google_ads_report As Workbook
Dim FromPath As String

'   Get path from cell C14 on Report tab
FromPath = Workbooks("Monthly Report - Master.xlsm").Sheets("Macros").Range("C14")

'   Make sure there is a backslash at the end of the from path
If Right(FromPath, 1) <> "\" Then FromPath = FromPath & "\"


'Set wkb = ThisWorkbook
Set google_ads_report = Workbooks.Open(FromPath & "hi.xlsx")

不允许您使用 new 关键字创建此类型的实例。

还有另一个简单的解决方案:

GA_Transactions = VBA.FileSystem.Dir("C:\Users\tom\Desktop\Analytics Google Ads Revenue - Monthly*.xlsx")

Workbooks.Open "C:\Users\tom\Desktop\" & GA_Transactions

答案 5 :(得分:0)

感谢@TehauCave 的回答,这是我的起点,我可以想出一种方法来定义一个也关心参数类型的类型。

export type Constructor<T, TArgs extends any[] = any> = Function & {
    prototype: T,
    apply: (this: any, args: TArgs) => void
};

以上类型都可以使用

  • 无论参数类型如何:

    Constructor<YourAbstractClass>
    

  • 限制参数类型:

    Constructor<YourAbstractClass, [number, string, boolean]>
    

使用 Constructor 类型,还可以推断给定构造函数的参数类型:

type ConstructorParameters<T extends Constructor<any>> = T extends Constructor<any, infer TParams> ? TParams : never;

然后,

ConstructorParameters<YourAbstractClass> // e.g., [number, string, boolean]