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

问题描述

我有一个 Foo 类,它有一个静态 instances 属性保存对所有创建的实例的引用。然后,我有一个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";
}

然而,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)

我尝试将 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)
    ...
}

看起来我的问题与 TypeScript 存储库中关于多态“this”的 this issue 相关。这是真的吗,我想做的事情目前是不可能的,或者我错过了什么?

游乐场链接 here

解决方法

TypeScript 已正确识别错误。 在您的情况下,静态实例数组将包含 Foo 和 Bar 的实例。

考虑将其添加到您的示例中并检查日志:

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

如果要将 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

,

那个 Bar 正在扩展 Foo 并不意味着已经声明的变量改变了它们的类型。因此,静态变量 'instance' 将始终是 Foo[] 类型,因为您在 Foo 类中将其声明为类型。 我认为“this”不起作用,因为“this”指的是一个对象,而在静态上下文中,它们不是 this 可以指向的对象。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...