简体   繁体   English

将静态属性的类型设置为实例类型的数组

[英]Set type of static property to an array of the instance type

I have a class Foo that has a static instances property holding references to all created instances.我有一个Foo类,它有一个静态instances属性,其中包含对所有创建的实例的引用。 Then, I have a class Bar extending Foo :然后,我有一个类Bar扩展Foo

class Foo {
    static instances: Foo[];

    fooProp = "foo";

    constructor() {
        let ctor = this.constructor as typeof Foo;
        ctor.instances.push(this);
    }
}

class Bar extends Foo {
    barProp = "bar";
}

However, the type of Bar.instances is Foo[] , rather than Bar[] , which causes the following error:但是, Bar.instances的类型是Foo[] ,而不是Bar[] ,这会导致以下错误:

let foo = new Foo();
let bar = new Bar();

Foo.instances[0].fooProp; // works
Bar.instances[0].barProp; // Property 'barProp' does not exist on type 'Foo'. ts(2339)

I tried using InstanceType<this> for the type of instances , but it still wouldn't work:我尝试使用InstanceType<this>作为instances类型,但它仍然不起作用:

class Foo {
    static instances: InstanceType<this>[]; // A 'this' type is available only in a non-static member of a class or interface. ts(2526)
    ...
}

It looks like my problem is related to this issue in the TypeScript repo regarding a polymorphic "this".看起来我的问题与 TypeScript 存储库中关于多态“this”的问题有关。 Is this true and what I want to do is currently impossible, or I'm missing sometihng?这是真的吗,我想做的事情目前是不可能的,或者我错过了什么?

Playground link here .游乐场链接在这里

TypeScript has correctly identified the error. TypeScript 已正确识别错误。 In your case, static instances array will hold instances of Foo and Bar alike.在您的情况下,静态实例数组将包含 Foo 和 Bar 的实例。

Consider adding this to your example and examine the logs:考虑将其添加到您的示例中并检查日志:

console.log(Foo.instances[0] instanceof Foo); // true
console.log(Foo.instances[0] instanceof Bar); // false, barProp will not exist on this instance

console.log(Foo.instances[1] instanceof Foo); // true
console.log(Foo.instances[1] instanceof Bar); // true, barProp would be 'bar'

Playground link 游乐场链接

If you want to store all instances of Foo in one array and all instances of Bar in another, you need to override the static instances in the Bar class:如果要将 Foo 的所有实例存储在一个数组中,并将 Bar 的所有实例存储在另一个数组中,则需要覆盖 Bar 类中的static instances

class Bar extends Foo {
    static instances: Bar[] = []

    barProp = 'bar';
}
console.log(Foo.instances.length); // 1
console.log(Foo.instances[0].fooProp); // 'foo'

console.log(Bar.instances.length); // 1
console.log(Bar.instances[0].barProp); // 'bar'

Playground link 游乐场链接

That Bar is extending Foo doesn't mean, that already declared variables change their type. Bar 正在扩展 Foo 并不意味着已经声明的变量会改变它们的类型。 So the static variable 'instance' will always be of type Foo[] because you declared it as that in your Foo class.因此,静态变量 'instance' 将始终是 Foo[] 类型,因为您在 Foo 类中将其声明为类型。 I think 'this' will not work, because 'this' refers to an object and in the static context their is no object to which this can point to.我认为“this”不起作用,因为“this”指的是一个对象,而在静态上下文中,它们不是 this 可以指向的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM