问题描述
type Constructor<T> = new (...args: any[]) => T;
function f1<T extends {}>(naked: Constructor<T>): any {
return class dressed extends naked { } // error
}
function f2<T extends Constructor<{}>>(naked: T): any {
return class dressed extends naked { } // ok
}
f1
说'dressed' is assignable to the constraint of type 'T',but 'T' Could be instantiated with a different subtype of constraint '{}'.
解决方法
令人困惑的是Constructor<T>
类型,因为实际上我们永远无法在类mixin语法中指定其通用参数T
。
有了一个简单/非通用的定义,我们自然可以选择编写一个f2
这样的类mixin:
type Constructor = new (...args: any[]) => any;
function Dressed<T extends Constructor>(Base: T) { // Note: no `: any` return type so that the type inference works.
return class extends Base {}
}
如果在其他地方需要通用的Constructor
类型,我们仍然可以指定默认类型来继续编写<T extends Constructor>
,这很容易引起误解:
type Constructor<T = {}> = new (...args: any[]) => T;