【问题标题】:Set type of static property to an array of the instance type将静态属性的类型设置为实例类型的数组
【发布时间】:2021-07-21 07:11:56
【问题描述】:

我有一个类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

【问题讨论】:

  • tl;dr TypeScript 不跟踪突变。 push 方法会改变您的原始数组。见我的文章:catchts.com/mutations

标签: typescript this typescript-class


【解决方案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'

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多