我们有一个这样定义的类
const A = class<T> {a: T}
目标是使用参数string
描述此类的实例的类型
目前我拥有的是
const instanceType: InstanceType<typeof A>
但是我不知道如何传递类型参数
答案 0 :(得分:1)
我不会问你为什么不只是以“正常方式”做事。那是您的事!
我认为这是缺少generic values或其他higher order types的语言所困扰的其中一种。当您“正常”定义类时:
class B<T> { b!: T }
TypeScript为实例创建一个新的命名通用 type B<T>
,并为构造函数创建一个新的命名为非通用 value B
, (其类型为通用构造函数),如下所示:
type B<T> = {b: T};
declare const B: new<T>()=>B<T>;
因此,在这种情况下,如果要引用将T
设置为string
实例化的实例类型,就可以了:
type InstanceOfBString = B<string>; // okay
但是您执行此操作的方式将创建命名的 value ,但不会创建命名的类型:
const A = class <T> { a!: T };
因此,现在您没有名为A
的类型可以使用:
type InstanceOfAString = A<string>; // error, cannot find name A
由于值A
不是通用的(因为没有通用值),所以您也不能写(typeof A)<T>
。
更糟糕的是,您目前无法使用conditional types来检查A
的类型以插入通用参数。从3.3开始,这是TS的design limitation。从根本上说,缺少高阶类型支持已成为我们的障碍。有些possible changes可能会解决此问题,但尚未使用该语言。
如果我们不能仅在类型级别上做到这一点,就可以通过运行时效果来做到这一点:
const instanceOfAString = new A<string>();
type InstanceOfAString = typeof instanceOfAString;
如果您不想仅仅为了获取类型而实际调用构造函数,则可以尝试使用控制流来阻止它:
if (false) {
// never called
var instanceOfAString = new A<string>();
}
type InstanceOfAString = typeof instanceOfAString;
构造函数永远不会在运行时真正调用,但是类型系统仍会为instanceOfAString
确定一个您可以抓住的类型。是的,它在运行时并不是完全不可见的……它出现在发出的JavaScript中,即使它实际上什么也不做。这是一种解决方法。
有an old proposal可以让您执行类似type InstanceOfAString = typeof (new A<string>())
的操作,而无需在运行时调用任何东西,但这也不被支持。所以这是我能得到的最接近的。
另一种可行的方法是自己创建类型A
,但要花一些代码重复:
const A = class <T> { a!: T };
type A<T> = { a: T };
现在您可以“正常”使用它:
type InstanceOfAString = A<string>;
但是,当然,如果A
具有很多属性,则实际上您将它们列出两次。
无论如何,希望其中一个想法能有所帮助。祝你好运!