打字稿:类型 ConstructorParameters 不接受泛型
Posted
技术标签:
【中文标题】打字稿:类型 ConstructorParameters 不接受泛型【英文标题】:Typescript: type ConstructorParameters does not accept generic 【发布时间】:2020-04-13 08:20:52 【问题描述】:使用 typescript 3.7,我有一个带有属性的接口,该属性旨在接受构造函数:
interface IConstruct<T>
type: new (...args:ConstructorParameters<T>) => T;
我的想法是IConstruct<User>
将有一个属性type: User
。
但是编译器告诉我 T
不能在那里使用。这是为什么呢?
TS2344:类型 T 不满足约束 'new (...args: any) => any'
【问题讨论】:
【参考方案1】:ConstructorParameters
的类型如下所示:
type ConstructorParameters<T extends new (...args: any) => any> =
T extends new (...args: infer P) => any ? P : never;
所以类型参数T
本身必须扩展某种由约束extends new (...args: any) => any
定义的构造函数。像这样写上面的例子,你应该很高兴:
class User
constructor(public name: string)
// add constructor function type constraint for T
interface IConstruct<T extends new (...args: any) => any>
// we can use built-in InstanceType to infer instance type from class type
type: new (...args: ConstructorParameters<T>) => InstanceType<T>;
type UserConstruct = IConstruct<typeof User>
const constr: UserConstruct =
type: User
constr.type // new (name: string) => User
const userInstance = new constr.type("John") // userInstance: User
console.log(userInstance.name) // John
Playground
【讨论】:
感谢您的提示。当您声明您的类型T1
时,您为什么使用 typeof User
而不是 User
? User
不是已经是一个类型了吗?
@BeetleJuice 不完全是,有区别:User
是实例的类型,typeof User
是实际的类类型。 Here 是文档中的一个很好的例子。
@BeetleJuice 更新了答案以在调用IConstruct.type
构造函数时返回T
的实例类型(这可能是您想要的)。我还为示例提供了更多详细信息,希望对您有所帮助。
ConstructorParameters
的类型定义中,? P : never
是什么? never
是对从不执行的构造函数的引用——即抽象类的构造函数签名吗?
@CraigHicks 不,? :
构造是 conditional type,never
类型系统中的底部类型。这意味着没有任何东西可以分配给它,因此如果 TS 无法 infer 构造函数参数,您可以在此处将其用作某种类型错误指示。以上是关于打字稿:类型 ConstructorParameters 不接受泛型的主要内容,如果未能解决你的问题,请参考以下文章