Typescript泛型,泛型中的新关键字扩展



在阅读关于装饰器的TS文档时,发现了以下语法:

function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
return class extends constructor {
newProperty = "new property";
hello = "override";
}
}

我不完全理解使用的以下泛型

<T extends {new(...args:any[]):{}}>

我通常理解泛型,也理解泛型中的extends关键字。然而,我现在想了解以下语法{new(...args:any[]):{}}的含义,特别是在泛型表达式中使用new、扩展...运算符和对象文字语法{}

{new(...args:any[]):{}}这个结构的总体含义如下:

"具有接受任意类型的可变数量的参数的构造函数的某个对象";。

...args是一个javascript(因此也是typescript(变量参数声明:

function f(...args: string[]) {}
f("asd", "a", "v")

在这种情况下,{}返回类型只是字面上的空对象。

则类型脚本extend释放了函数params的约束(因为任何函数params组合都确实扩展了...args: any[](对于返回类型(因为任何对象都扩展了{},构造函数隐式返回构造的对象(

因此该签名意味着:";给我任何可以通过new关键字创建的东西,不管怎样">

ts操场上的小例子

它基本上是一个类检查(一个带有构造函数的对象(

{new ... }

这些左大括号和右大括号表示我们正在对象内部工作。类似:{num: number}

new(...args: any[])

这里的new关键字强调了我们正在寻找具有构造函数的东西。...args: any[]只是声明该类型不关心该构造函数的参数。

更具体地说,具有三点状态的...args可以有任何数量的参数,而any[]意味着这些参数可以具有any类型,这意味着它们绝对可以是任何东西。

然后:

: {}

这说明构造函数应该返回一个对象,如果它是为类返回的,那么它很可能会返回。

我从来没有见过它这样写,通常情况下,只写这样就足够了:

<T extends new (...args: any[])=>Object>

原始脚本需要封装在{...}中的原因是,使用冒号:而不是箭头=>会混淆类型脚本,因为它不希望在对象或类型定义之外使用冒号。

总而言之,拥有这种类型是有意义的,因为它确保了这个装饰器只能应用于一个类,并在装饰器本身中对其进行类型化。

最新更新