首页 > 解决方案 > 引用超类 (TS) 中子类的静态字段

问题描述

在使用类和子类时,在基类中定义泛型方法并在其中使用实例特定变量是很常见的。

但是,我无法弄清楚如何从基类的方法中获取正确的静态类变量。

以下面的代码为例:

abstract class Unit<T extends Symbol> {
    public static factors: {};

    constructor(
        protected readonly type: T,
        protected value: number
    ) {}
}

class Energy extends Unit<typeof EnergySym> {

    public static factors = {
        J: 1,
        kJ: 1e3,
        MJ: 1e6,
        GJ: 1e9,
    };

    constructor(value: number, unit: keyof typeof Energy.factors = 'J') {
        super(EnergySym, value * Energy.factors[unit]);
    }

    get(unit: keyof typeof Energy.factors) {
        return this.value / Energy.factors[unit];
    }
}

get如果我们可以将方法放在基类中,通过到达当前类的静态字段,在添加更多类型的单元时需要更少的代码。

例如,在 Python 中,您可以使用self.__class__.foo. 有 JavaScript 等价物吗?

此外,有没有办法为此添加正确的类型?

标签: javascripttypescriptinheritancestatic

解决方案


我设法通过向基类添加一个附加类型参数来解决它,该基类是所有允许单元的联合。

仍然需要为每个子类定义允许的单位,这可以通过 来完成type FooUnits = keyof typeof Foo.units,假设它们被定义为类本身的静态字段。

人们仍然可以想象这可以用更少的代码来完成,但据我所知,没有 TS 支持。

abstract class Unit<T extends Symbol, U> {

    public value: number;

    constructor(
        protected readonly type: T,
        value: number,
        public unit: U
    ) {
        this.value = value * this.constructor['units'][unit]
    }

    get(unit: U): number {
        return this.value / this.constructor['units'][unit];
    }
}

type EnergyUnits = keyof typeof Energy.units;

export class Energy extends Unit<typeof EnergySym, EnergyUnits> {

    public static units = {
        J: 1,
        Wh: 3.6e3,
    };

    constructor(value: number, unit: EnergyUnits = 'J') {
        super(EnergySym, value, unit);
    }
}

推荐阅读