我已经知道如何为函数参数(例如下面的foo
函数的参数)添加“ newable”(即具有构造函数)约束,但是相同的技术不适用于泛型类型参数。
这是为什么以及如何解决?
type NoParameterCtor<T> = { new(): T }
function foo<T>(ctor: NoParameterCtor<T>) { }
interface Bar<T extends NoParameterCtor<T>> { }
class Zoo { }
foo(Zoo)
// no compiler error
class Zar implements Bar<Zoo> { }
// Type 'Zoo' does not satisfy the constraint 'NoParameterCtor<Zoo>'
答案 0 :(得分:2)
如评论中所述,T extends NoParameterCtor<T>
是一个不寻常的约束,表示“ T
是构造自身的新构造函数”。除非您试图描述自我复制的构造函数,否则这不是您的意思。
如果您只想让T
是“任何可更新的”,则无需关心实例类型。假设您使用的是TS3.0或更高版本,尽管也可以使用unknown
,但是可以使用any
来表示任何类型。所以也许你想Bar
成为
interface Bar<T extends NoParameterCtor<unknown>> { }
以下内容仍然无效:
class Zar implements Bar<Zoo> { } // error!
// Zoo does not satisfy the constraint NoParameterCtor<unknown>
这是因为类型Zoo
是不可更新的;它是Zoo
类的实例类型。我不知道您是否对TypeScript中的the difference between named values and named types感到困惑,但如果您这样做的话,您会很好。简而言之,class Zoo {}
引入了一个名为Zoo
的 type ,它是该类的实例的类型,还引入了一个名为{{1}的 value 。 },即此类实例的构造函数。并且Zoo
值的类型不是Zoo
类型。要引用Zoo
构造函数值的类型,您需要改用Zoo
:
typeof Foo
我还假设您已经剥离了class Zar implements Bar<typeof Zoo> { } // okay
,Bar
和Zar
的内容,因为它们与此处无关。但要清楚一点,因为TypeScript使用structural typing,所以空接口几乎可以匹配所有内容。如果Zoo
需要访问Bar
的实例类型,则可以使用内置库类型别名InstanceType<>
来获取它:
T
希望有帮助。祝你好运!