打字稿工厂 class 和通用不工作

Typescript factory class and generic not working

以如下代码为例: 我正在尝试生成一个工厂 class 来序列化和反序列化我的实例,以便我可以保存它们并从数据库中读取它们。

abstract class Brush {
    private _opacity: number;

    constructor(opacity: number) {
        this._opacity = opacity;
    }

    public get opacity(): number {
        return this._opacity;
    }
}

class SolidColorBrush extends Brush {
    private _color: string;

    constructor(
        opacity: number,
        color: string) {
        super(opacity);

        this._color = color as string;
    }

    public get color(): string {
        return this._color;
    }

    public static fromJSON(json: string): SolidColorBrush {
        const parsedJson: any = JSON.parse(json);

        const solidColorBrush = new SolidColorBrush(
            parsedJson.opacity,
            parsedJson.color);

        return solidColorBrush;
    }

    public toJSON(): string {
        const json: string = JSON.stringify({
            opacity: this.opacity,
            color: this.color
        });

        return json;
    }
}

class GradientBrush extends Brush {
    private _color1: string;
    private _color2: string;

    constructor(
        opacity: number,
        color1: string,
        color2: string) {
        super(opacity);

        this._color1 = color1;
        this._color2 = color2;
    }

    public get color1(): string {
        return this._color1;
    }
    public get color2(): string {
        return this._color2;
    }

    public static fromJSON(json: string): GradientBrush {
        const parsedJson: any = JSON.parse(json);

        const gradientBrush = new GradientBrush(
            parsedJson.opacity,
            parsedJson.color1,
            parsedJson.color2);

        return gradientBrush;
    }

    public toJSON(): string {
        const json: string = JSON.stringify({
            opacity: this.opacity,
            color1: this.color1,
            color2: this.color2
        });

        return json;
    }
}

class BrushFactory {
    // this does not work
    public fromJson<T extends Brush>(
        t: new (...args: any[]) => T,
        json: string): T {
        switch (t) {
            case SolidColorBrush:
                return SolidColorBrush.fromJSON(json);
            case GradientBrush:
                return GradientBrush.fromJSON(json);
            default:
                throw new Error();
        }
    }

    // this works
    public fromJson2(
        t: new (...args: any[]) => Brush,
        json: string): Brush {
        switch (t) {
            case SolidColorBrush:
                return SolidColorBrush.fromJSON(json);
            case GradientBrush:
                return GradientBrush.fromJSON(json);
            default:
                throw new Error();
        }
    }

    // this does not work
    public toJson<T extends Brush>(
        t: new (...args: any[]) => T,
        brush: T): string {
        switch (t) {
            case SolidColorBrush:
                return (brush as SolidColorBrush).toJSON();
            case GradientBrush:
                return (brush as GradientBrush).toJSON();
            default:
                throw new Error();
        }
    }

    // this works
    public toJson2(
        t: new (...args: any[]) => Brush,
        brush: Brush): string {
        switch (t) {
            case SolidColorBrush:
                return (brush as SolidColorBrush).toJSON();
            case GradientBrush:
                return (brush as GradientBrush).toJSON();
            default:
                throw new Error();
        }
    }
}

为什么toJSON不编译而toJSON2编译? fromJSON 和 fromJSON2 相同。

在这种情况下,我更愿意为我的工厂模式使用泛型。 自 IMO 以来,它更容易使用并且更不容易出错。 任何解决方法将不胜感激?

Re fromJSON 错误:测试 t 等于您的 class 之一不会自动更改 T 的类型。那将是类似于 this open suggestion.

的功能

Re toJSON 错误:不幸的是,在这种情况下,TypeScript 不认为 TBrush subclass 具有可比性。有关详细信息,请参阅 this issue

关于如何编写代码:与直接在 Brush 子 class 上调用 fromJSON 相比,我看不出 BrushFactory.fromJson 对你有什么好处,因为无论如何你必须有 subclass 才能传递到 BrushFactory.fromJson。同样,如果您将 toJSON 声明为 Brush class 上的抽象方法,那么您可以在任何 Brush 上调用它而无需 BrushFactory.toJson .