Как сделать интерфейс универсальных функций, которые возвращают экземпляры дочерних классов? - PullRequest
0 голосов
/ 05 октября 2019

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

Это то, что я думал, будет работать:

export interface ChildPagesNavigators {
  [name: string]: <T extends Page>() => Promise<T>
}

И затем я использую егов абстрактном классе:

export abstract class Page {
  constructor(protected driver: ThenableWebDriver) {}
  abstract navigate(): Promise<void>;
  abstract open: ChildPagesNavigators;
}

Я пытаюсь создать дочерний класс страницы, который реализует отсутствующее свойство open.

export class Landing extends Page {
  async navigate(): Promise<void> {
    return this.driver.get(BASE_URL);
  }

  open = {
    async login(): Promise<Login> {
      await this.driver.findElement(By.linkText("login")).click();
      return new Login(this.driver);
    }
  };
}

Я также определяю класс Login для расширенияPage.

Здесь я получаю сообщение об ошибке:

Error:(11, 3) TS2416: Property 'open' in type 'Landing' is not assignable to the same property in base type 'Page'.
  Type '{ login(): Promise<Login>; }' is not assignable to type 'ChildPagesNavigators'.
    Property 'login' is incompatible with index signature.
      Type '() => Promise<Login>' is not assignable to type '<T extends Page>() => Promise<T>'.
        Type 'Promise<Login>' is not assignable to type 'Promise<T>'.
          Type 'Login' is not assignable to type 'T'.

На самом деле Login расширяет Page, поэтому должно соответствовать T требованию.

Iхотел бы определить ChildPagesNavigators интерфейс, чтобы он мог содержать любую функцию, которая возвращает экземпляр класса, который расширяет Page. Как это сделать?

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