打字稿:类型 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&lt;User&gt; 将有一个属性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) =&gt; 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 而不是 UserUser 不是已经是一个类型了吗? @BeetleJuice 不完全是,有区别:User 是实例的类型,typeof User 是实际的类类型。 Here 是文档中的一个很好的例子。 @BeetleJuice 更新了答案以在调用IConstruct.type 构造函数时返回T 的实例类型(这可能是您想要的)。我还为示例提供了更多详细信息,希望对您有所帮助。 ConstructorParameters的类型定义中,? P : never是什么? never 是对从不执行的构造函数的引用——即抽象类的构造函数签名吗? @CraigHicks 不,? : 构造是 conditional type,never 类型系统中的底部类型。这意味着没有任何东西可以分配给它,因此如果 TS 无法 infer 构造函数参数,您可以在此处将其用作某种类型错误指示。

以上是关于打字稿:类型 ConstructorParameters 不接受泛型的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中声明函数类型

强类型的打字稿集合

打字稿错误 - 属性“标题”的类型不兼容

打字稿中的通用对象类型

打字稿:类型“”没有索引签名

Reactj,类型中缺少打字稿属性'setState'