moștenire - Există un echivalent pentru „sealed” sau „final” în TypeScript?


Încerc să implementez o metodă într-o superclasă care ar trebui să fie disponibilă pentru utilizare, dar să nu poată fi modificată în subclase. Considerați asta:

export abstract class BaseClass {
    universalBehavior(): void {
        doStuff(); // Do some universal stuff the same way in all sub classes
        specializedBehavior(); // Delegate specialized stuff to sub classes
    }

    protected abstract specializedBehavior(): void;
}

Intenția mea ar fi ca orice subclasă a BaseClass să nu fie doar liberă să omită implementarea universalBehavior(), ci să nu fie nici măcar permisă să furnizeze o implementare. Nu este oare acest lucru (încă) posibil în TypeScript? Intellisense se plânge atunci când omit implementarea în subclasele mele. Cel mai bine ce par să pot face este acesta:

export class SubClass extends BaseClass {
    universalBehavior(): void {
        super.universalBehavior();
    }

    specializedBehavior(): void {
        // sub class' implementation
    }
}

Evident, acest lucru este problematic deoarece trebuie să mă asigur că nicio subclasă nu implementează vreodată universalBehavior() cu altceva decât un apel la super.universalBehavior().

Răspuns #1

Nu, în momentul în care se scrie acest lucru, nu există. Există o propunere pentru un astfel de cuvânt cheie care este încă luată în considerare, dar care poate sau nu să fie vreodată implementată.

Vezi :

  • github.com/Microsoft/TypeScript/issues/9264, și
  • github.com/Microsoft/TypeScript/issues/8306

Răspunsul #2

Exemplu de implementare hack a 'metodei sigilate' ca proprietate readonly de tip funcție care generează eroare de compilator atunci când se încearcă suprascrierea în clasa extinsă:

abstract class BaseClass {
    protected element: JQuery<HTMLElement>;
    constructor(element: JQuery<HTMLElement>) {
        this.element = element;
    }
    readonly public dispose = (): void => {
        this.element.remove();
    }
}

class MyClass extends BaseClass {
    constructor(element: JQuery<HTMLElement>) {
        super(element);
    }
    public dispose(): void { } // Compiler error: "Property 'dispose' in type 'MyClass' is not assignable to the same property in base type 'BaseClass'"
}

TypeScript 2.0 suportă clase „finale” prin utilizarea constructorului privat:

class A {
    private constructor(){}
}

class B extends A{} //Cannot extend a class 'A'. Class constructor is marked as private.ts(2675)