TypeScript:静态属性和继承

13

我对TypeScript(1.8)还很陌生,我在继承和静态属性方面遇到了一个小问题。

以下是我当前运行的测试代码:

class A {
    public static Items = {
        FOO: 'A'
    };

    public show() {
        alert(this.constructor.Items.FOO);
    }
} 

class B extends A {
    public static Items = {
        FOO: 'B'
    };
}

var a = new A();
var b = new B();

a.show(); // alert "A"
b.show(); // alert "B"

TypeScript Playground链接

这段代码可以正常运行,两个警告框也都按预期显示。

但是 TypeScript 编译器会抛出一个错误:Property "Items" does not exist on type "Function"

我理解这个警告,从 TypeScript 的角度来看完全正确,但我应该如何在让编译器满意的同时获得同样的结果?this.Items.FOO 显然不起作用,我也没找到类似于 self 的东西或者其他替代方式……

我有什么遗漏吗?

提前感谢!


2
注意,当您引入一个没有静态 Items 属性的额外子类时(例如 class C extends A {}),您的 show 方法将不起作用。 - Mattias Buelens
2个回答

10
今天有一个类似的问题:在TypeScript中,如何通过不使用类名来在子类中使用不同的静态方法
这里有一个关于让this.constructor返回正确类型的讨论/建议:T.constructor应该是类型T
至于现在可能适用于您的解决方案:
不使用static:
class A {
    public show() {
        alert(this.getItems().FOO);
    }

    protected getItems() {
        return {
            FOO: 'A'
        }
    };
}

class B extends A {
    protected getItems() {
        return {
            FOO: 'B'
        }
    }
}

(代码演示)

使用 typeof 的静态方法:

class A {
    public static Items = {
        FOO: 'A'
    };

    public show() {
        alert((<typeof A | typeof B> this.constructor).Items.FOO);
    }
}

(代码在 playground 中)

构造函数接口中的静态属性:

interface AConstructor {
    new (): A;
    Items: any;
}

class A {
    public static Items = {
        FOO: 'A'
    };

    public show() {
        alert((this.constructor as AConstructor).Items.FOO);
    }
}

(code in playground)


请使用您的typeof解决方案,否则无法捕获B.Items -> B.ItemsRenamed。alert((<typeof A|typeof B>this.constructor).Items.FOO); - mk.
@mk,谢谢,我更新了我的答案,尽管我认为当你有两个以上的类时,这种解决方案并不是很有用。在我看来,第一个选项(没有静态)更好。 - Nitzan Tomer

6

我理解这个警告,并且从 TypeScript 的角度来看,它是完全正确的。

对的 - 这有点像继承,但通常不适用于静态属性。为了解决这个问题,可以使用 any 来禁用类型检查:

alert((<any>this.constructor).Items.FOO);

这种情况通常发生在转换旧的js代码时,但在编写新的TS代码时应该避免。如果您想正确地执行此操作,则需要(如您可能已经知道的那样)在两个类中实现和覆盖getItems或类似方法以返回相应的Items,并从show调用该方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接