0

我有一个类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.instancesFoo[],而不是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 repo 中关于多态“this”的问题有关。这是真的吗,我想做的事情目前是不可能的,或者我错过了什么?

游乐场链接在这里

4

2 回答 2

1

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'

游乐场链接

如果要将 Foo 的所有实例存储在一个数组中,并将 Bar 的所有实例存储在另一个数组中,则需要覆盖static instancesBar 类中的 :

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'

游乐场链接

于 2021-07-21T07:55:14.563 回答
0

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

于 2021-07-21T07:41:35.307 回答