Фабричный класс Typescript и общий не работает - PullRequest
0 голосов
/ 13 сентября 2018

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

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

1 Ответ

0 голосов
/ 15 сентября 2018

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

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

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

нет необходимости.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...