如何在打字稿中扩展工厂方法

How to extend factory method in typescript

上下文:

我有一些 class,它有时会产生自己的实例,并且工作正常。 但是现在我想扩展 class 并意识到我会得到一个父 class.

的实例

示例:

class Line {
    constructor(protected length: number) {}
    
    divide(into: number): Line[] {
        const size: number = Math.ceil(this.length / into);

        return (new Array(into)).map(() => new Line(size));
    }
}

class BoldLine extends Line {
    constructor(protected length: number, private width: number) {
        super(length);
    }

    getWidth() {
        return this.width;
    }
}

const line: BoldLine = new BoldLine(10, 2);

line.divide(2); // <== I'll get Line[] but would like to have BoldLine[];

问题:

我怎样才能始终获得 this.constructor class 的实例,即使是在继承之后? 我怎样才能无缝地做到这一点,w/o 将构造函数名称作为参数传递给 divide 方法?

谢谢。

不确定是否有更好的方法,但我会这样做。

class Line {
    constructor(protected length: number) {}
    
    divide(into: number): this[] {
        const size: number = Math.ceil(this.length / into);

        return (new Array(into)).map(() => new (this.constructor as new (length: number) => this)(size));
    }
}

class BoldLine extends Line {
    constructor(protected length: number, private width) {
        super(length);
    }

    getWidth() {
        return this.width;
    }
}

const line: BoldLine = new BoldLine(10, 2);

line.divide(2);

如果您需要将 width 属性(未类型化,因此它可以是任何内容,包括未定义)传播给子 classes,那么您需要一个额外的工厂当前 class.

实例的方法
class Line {
    constructor(protected length: number) { }

    protected create(length: number): this
    {
        return new Line(length) as this;
    }
    
    divide(into: number): this[] {
        const size: number = Math.ceil(this.length / into);

        return (new Array(into)).map(() => this.create(size));
    }
}

class BoldLine extends Line {
    constructor(protected length: number, private width) {
        super(length);
    }

    protected create(length: number): this
    {
        return new BoldLine(length, this.width) as this;
    }
    
    getWidth() {
        return this.width;
    }
}

const line: BoldLine = new BoldLine(10, 2);

line.divide(2);