如何键入Constructor< T> =功能& {prototype:T}`是否适用于TypeScript中的Abstract构造函数类型? [英] How does `type Constructor<T> = Function & { prototype: T }` apply to Abstract constructor types in TypeScript?
问题描述
关于TypeScript中的Abstract构造函数类型有一个问与答,我想知道以下问题的答案:
There is this Q&A about Abstract constructor types in TypeScript, which is a question I would like to know the answer to:
不幸的是,已被接受答案不过是一个无法解释的单行代码: type Constructor< T> =功能& {prototype:T}
Unfortunately, the accepted answer is little more that an unexplained one-liner: type Constructor<T> = Function & { prototype: T }
看来,这个答案对提问者来说已经足够了,它是公认的答案,但是我无法
It appears that this answer is good enough for the asker, it is the accepted answer, but I'm unable to understand how the answer applies to the question.
我尝试在评论中提问,并尝试在聊天中询问某人以解释答案,但是徒劳无功。另外,我认识到,这与那个问题几乎没有什么不同,但这仍然是关于代码的独特问题。
I've tried asking in the comments, and I've tried asking someone in chat to explain the answer, but to no avail. Also, I recognize that this is only barely a different question from that one, but this is still a unique question about code.
如何使用功能和{prototype:T}
模仿已知构造函数类型的抽象类?
How can I use a type of Function & { prototype: T }
to emulate an abstract class of known constructor type?
推荐答案
在 JavaScript ,所有函数都有一个名为<$ c $的特殊属性c> prototype 。如果将函数用作构造函数(通过使用 new
进行调用),则构造的实例将以其为原型。这是ES2015之前的类在JavaScript中的工作方式:
In JavaScript, all functions have a special property called prototype
. If you use a function as a constructor (by calling it with new
), the constructed instance will have that as its prototype. This is how classes worked in JavaScript before ES2015:
// 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
ES2015引入了类
语法,在内部具有相同的行为方式...因此构造函数对象仍具有 prototype
属性,可从中继承构造的实例。
ES2015 introduced the class
syntax, which behaves the same way under the hood... and so constructor objects still have a prototype
property from which constructed instances inherit.
// 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
TypeScript通过声明对此进行建模所有函数都实现的Function
接口具有类型为 any
的原型
属性。此外,当使用 class
语法时,构造函数仍被视为 Function
和<$ c $ any
缩小为与构造的类实例相同的类型:
TypeScript models this by declaring that the Function
interface, which all functions implement, has a prototype
property of type any
. Furthermore, when the class
syntax is used, the constructor is still seen as a Function
, and the prototype
property of the constructor is narrowed from any
to the same type as the constructed class instance:
// 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
甚至抽象
TypeScript中的类具有 prototype
属性,该属性的类型与实例类型相同。因此,尽管您不能在抽象类构造函数上调用 new
,也不能将其与诸如 new()=>之类的可更新类型进行匹配。任何
,您仍然可以谈论其原型
:
Even abstract
classes in TypeScript have a prototype
property whose type is the same as the instance type. So while you can't call new
on an abstract class constructor, or match it to a newable type like new() => any
, you can still talk about its 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
却无法做到这一点,这意味着在TypeScript中可能是抽象的类构造函数是 Function
的子类型,其 prototype
属性是构造函数的实例类型。因此,您可以说
All this means that in TypeScript a possibly-abstract class constructor is (a subtype of) a Function
whose prototype
property is the instance type for the constructor. Thus, you can say that
type PossiblyAbstractConstructor<T> = Function & {prototype: T};
使用交点运算符将 Function
和对象与原型组合在一起
类型为 T
...
using the intersection operator to combine Function
and "object with a prototype
property of type T
"...
或类似的
interface PossiblyAbstractConstructor<T> extends Function {
prototype: T;
}
使用接口扩展以达到相同的效果...
using interface extension to achieve the same effect...
const fooConstructor: PossiblyAbstractConstructor<Foo> = Foo;
const barConstructor: PossiblyAbstractConstructor<Bar> = Bar;
这应该解释原始问题的答案如何适用。希望能有所帮助。祝好运!
That should explain how the original question's answer is applicable. Hope that helps. Good luck!
这篇关于如何键入Constructor< T> =功能& {prototype:T}`是否适用于TypeScript中的Abstract构造函数类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!