typescript1.8 - Referințierea unei clase fără nume pentru a folosi o metodă statică diferită în subclase în TypeScript


În ES6, poți face referire la metode statice prin this.constructor:

class MainClass {
  static info() {
    return "This is some information";
  }
  constructor() {
    this.info = this.constructor.info(); // Allows subclass to define different '.info()' method.
  }
}

class ChildClass extends MainClass {
  static info() {
    return "This information is from the child";
  }

  constructor() {
    super();
  }
}

Există o modalitate de a face asta în TypeScript? Vreau să pot suprascrie metoda statică a clasei superioare și să o folosesc din subclasă fără a redefini referința într-o metodă de instanță. În acest moment, singura modalitate pe care o cunosc pentru a accesa o metodă statică în TypeScript folosește numele clasei.

MainClass.info();

Dar dacă fac asta, subclasa va continua să folosească MainClass.info(); în loc de propria sa metodă .info().

Răspuns #1

Ce zici de asta:

interface MainClassConstructor {
    new (): MainClass;
    info(): string;
}

class MainClass {
    static info() {
        return "This is some information";
    }

    private info: string;

    constructor() {
        this.info = (this.constructor as MainClassConstructor).info(); // Allows subclass to define different '.info()' method.
    }
}

class ChildClass extends MainClass {
    static info() {
        return "This information is from the child";
    }

    constructor() {
        super();
    }
}

(cod în teren de joacă)

Editează

De asemenea, poți folosi typeof MainClass în locul interfeței MainClassConstructor pe care am adăugat-o:

class MainClass {
    static info() {
        return "This is some information";
    }

    private info: string;

    constructor() {
        this.info = (this.constructor as typeof MainClass).info(); // Allows subclass to define different '.info()' method.
    }
}

În plus, există o discuție/sugestie de a avea this.constructor să returneze tipul corect aici: T.constructor ar trebui să fie de tip T.

O altă opțiune este să folosiți suprascrierea metodei:

class MainClass {
    private info: string;

    constructor() {
        this.info = this.getInfo();
    }

    protected getInfo(): string {
        return "This is some information";
    }
}

class ChildClass extends MainClass {
    constructor() {
        super();
    }

    protected getInfo(): string {
        return "This information is from the child";
    }
}

Răspunsul #2

Verifică acest cod TypeScript:

class MainClass {
  static info() {
    return "This is some information";
  }
  info: string;

  constructor() {
    this.info = (this.constructor as any).info(); // Allows subclass to define different '.info()' method.
  }
}

class ChildClass extends MainClass {
  static info() {
    return "This information is from the child";
  }

  constructor() {
    super();
  }
}

Dacă ținta de compilare este ES6, acesta se compilează exact în codul pe care l-ai dat mai sus și funcționează bine. Funcționează bine și dacă este compilat în ES5.

Rețineți că am folosit un truc as any pentru a permite apelarea .info() pe funcția constructor.

Alternativ, ai putea suprascrie setarea lui this.info în fiecare clasă copil. În acest fel, nu ai avea nevoie de truc.