Заводской класс typescript и общий не работают

В качестве примера приведен следующий код: Я пытаюсь создать фабричный класс для сериализации и десериализации моих экземпляров, чтобы я мог сохранять и читать их из базы данных.

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. Любая работа будет оценена?

Какая у вас ошибка?

SLaks 13.09.2018 18:10

[ts] Тип 'typeof SolidColorBrush' не сопоставим с типом 'new (... args: any []) => T'. Тип SolidColorBrush не сопоставим с типом T.

Nicolas 13.09.2018 19:27
0
2
217
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В отношении ошибок fromJSON: проверка того, что t соответствует одному из ваших классов, не приводит к автоматическому изменению типа T. Это будет функция, аналогичная это открытое предложение.

В отношении ошибок toJSON: в данном случае, к сожалению, TypeScript не считает T и подкласс Brush сопоставимыми. См. Эта проблема для получения дополнительной информации.

Что касается написания кода: я не понимаю, что вам покупает BrushFactory.fromJson, по сравнению с вызовом fromJSON непосредственно в подклассе Brush, поскольку у вас в любом случае должен быть подкласс для перехода в BrushFactory.fromJson. Точно так же, если вы объявляете toJSON как абстрактный метод в классе Brush, вы можете вызывать его на любом Brush, и в BrushFactory.toJson нет необходимости.

Другие вопросы по теме