`type Constructor <T> = Function&{prototype:T}`如何应用于TypeScript中的Abstract构造函数类型?

Sep*_*eed 2 constructor abstract-class typescript

关于TypeScript中的Abstract构造函数类型的问答,这是我想知道的答案:

TypeScript中的抽象构造函数类型

不幸的是,被接受的答案仅是无法解释的一句话: type Constructor<T> = Function & { prototype: T }

看来,这个答案对提问者来说已经足够了,它是公认的答案,但是我无法理解该答案如何应用于问题。

我尝试在评论中提问,并且尝试在聊天中询问某人以解释答案,但无济于事。另外,我认识到这只是与那个问题完全不同的问题,但这仍然是关于代码的独特问题。

如何使用一种类型Function & { prototype: T }来模拟已知构造函数类型的抽象类?

jca*_*alz 5

JavaScript中,所有函数都有一个称为的特殊属性prototype。如果将函数用作构造函数(通过调用new),则构造的实例会将其作为原型。这是ES2015之前的类在JavaScript中的工作方式:

// ES5-flavored class 
function Foo() { } // a normal function 
Foo.prototype.prop = 0; // adding a property to Foo.prototype
var f = new Foo(); // using Foo as a constructor
f.prop; // the instance inherits the added property
Run Code Online (Sandbox Code Playgroud)

ES2015引入了class语法,该语法在幕后具有相同的行为...因此构造函数对象仍然具有prototype从中继承构造的实例的属性。

// ES2015-flavored class
class Foo { } // explicitly a class
Foo.prototype.prop = 0; // adding a property to Foo.prototype
const f = new Foo(); // using Foo as a constructor
f.prop; // the instance inherits the added property
Run Code Online (Sandbox Code Playgroud)

TypeScript通过声明Function所有函数实现的接口具有prototypetype属性来any对此建模。此外,当使用class语法时,构造函数仍视为a Function,并且构造函数prototype属性从缩小为与构造的类实例相同的类型:any

// TypeScript code
class Foo { 
  prop!: number;  // Foo has a prop
} 
Foo.prototype; // inspects as type Foo
Foo.prototype.prop = 0; // so this works
const f = new Foo(); // inspects as type Foo
f.prop; // inspects as type number
Run Code Online (Sandbox Code Playgroud)

即使abstractTypeScript中的类也具有prototype其类型与实例类型相同的属性。因此,尽管您不能调用new抽象类的构造函数,也不能将其与诸如的new() => any可更新类型进行匹配,但是您仍然可以谈论它prototype

// more TS code
abstract class Bar {
  abstract prop: number;
}
Bar.prototype; // inspects as type Bar
Bar.prototype.prop = 0; // so this works
const b = new Bar(); // whoops can't do this though
Run Code Online (Sandbox Code Playgroud)

所有这些意味着在TypeScript中,可能抽象的类构造函数是(的子类型)Functionprototype属性是该构造函数的实例类型。因此,您可以说

type PossiblyAbstractConstructor<T> = Function & {prototype: T};
Run Code Online (Sandbox Code Playgroud)

使用相交运算符组合Function和“具有prototype类型属性的对象T” ...

或类似

interface PossiblyAbstractConstructor<T> extends Function {
  prototype: T;
}
Run Code Online (Sandbox Code Playgroud)

使用接口扩展来达到相同的效果...

并且您知道以下内容有效:

const fooConstructor: PossiblyAbstractConstructor<Foo> = Foo;
const barConstructor: PossiblyAbstractConstructor<Bar> = Bar;
Run Code Online (Sandbox Code Playgroud)

那应该解释原始问题的答案如何适用。希望能有所帮助。祝好运!

  • 非常感谢。我想你帮我找到了我困惑的根源。我一直在想,这种技术将帮助我创建一些“抽象类 ConstructorTakesStringAsOnlyArgument”,以便拥有一组已知构造函数参数的扩展类。这种技术似乎是用于创建未知参数类型的抽象构造函数。这样对吗? (2认同)