Абстрактный внутренний класс в typescript

#javascript #typescript #ecmascript-6 #polymorphism

#javascript #typescript #ecmascript-6 #полиморфизм

Вопрос:

 abstract class Model {
    abstract class View extends ModelView<this>;

    getView(){
        return new View();
    }
}

abtract class ModelView<M extends Model> {}
  

 class Shape extends Model {
    View = class {
        constructor(){ console.log("view created"); }
    }
}
  

Я пытаюсь создать подобный код, который, на мой взгляд, хорошо структурирован.

Возможно ли это в react иметь класс как подкласс другого — и иметь его как абстрактное свойство (предпочтительно статическое).

Комментарии:

1. Я думаю, вы ищете термин внутренний класс , а не «подкласс»

2. Почему бы и нет? Он полиморфный

Ответ №1:

Кажется, я понял это.

В TS подобный синтаксис attribute: Item { ... означает, что attribute это экземпляр класса Item . Если вы хотите attribute быть элементом класса (а не экземпляром), вы должны использовать синтаксис, подобный этому attribute: { new (...args): Item } {... . Итак, окончательный код должен выглядеть следующим образом:

 abstract class ModelView<M extends Model> {}


abstract class Model {
    public View: { new(...args): ModelView<Model> };

    getView(): ModelView<Model> {
        return new this.View();
    }
}
  

и затем в Shape классе вы можете сделать это:

 class Shape extends Model {
    View = class {
        constructor(){ console.log("view created"); }
    }
}
  

И код будет типобезопасным.

<a rel="noreferrer noopener nofollow" href="https://www.typescriptlang.org/play/index.html#src=abstract class ModelView {}

abstract class Model {
public View: { new(…args): ModelView };

getView(): ModelView {
return new this.View();
}
}

class Shape extends Model {
View = class {
constructor(){ console.log(«view created»); }
}
}» rel=»nofollow noreferrer»>Игровая площадка

——Отредактировано——

Если вы хотите, чтобы просмотр был статическим и доступным только для чтения, вам нужно немного изменить getView реализацию для этого:

 public static readonly View: { new(...args): ModelView<Model> };

getView(): ModelView<Model> {
    return new Model.View();
}

  

Комментарии:

1. Рад помочь 🙂 Не могли бы вы одобрить мой ответ, чтобы он был более заметен для других?

2. Конечно, проверьте отредактированную часть ответа

3. Поскольку представление больше не является абстрактным, getView из базового Model класса не будет работать полиморфно

4. View необходимо наследовать от ModelView<Model> , а ModelView может быть абстрактным, но вы не сможете сделать это View = ModelView в Shape классе. Также ModelView не наследует от Model, он требует его только в универсальном типе

5. Это то решение, которое вы ищете?

Ответ №2:

Вы просто ищете что-то вроде следующего?

 abstract class Model {

  // don't use "class" here; the type of a constructor has new(...) in it:
  abstract View: new () => ModelView<this>;

  getView() {
    return new this.View(); // View is an instance property, need "this"
  }
}

abstract class ModelView<M extends Model> { }

class Shape extends Model {
    View = class {
        constructor(){ console.log("view created"); }
    }
}
  

Если это соответствует вашим потребностям, отлично. Если нет, пожалуйста, отредактируйте свой вопрос, чтобы включить больше информации о вашем варианте использования. Надеюсь, это вам поможет. Удачи!

Комментарии:

1. На самом деле я предпочитаю этот ответ, поскольку в нем используются более краткие new () => ModelView<this>; обозначения. Спасибо за ответ

2. Не думаю, что у вас вообще могут быть абстрактные статические свойства, нет.

3. Будет ли следующей лучшей вещью абстрактная getViewClass функция? Таким образом, каждая модель должна объявлять представление, которое все еще может быть статическим

4. Кроме того, это работает не так, как ожидалось. В классе example Shape при объявлении View возникает ошибка

5. Я не получаю никакой подобной ошибки при его тестировании, поэтому без дополнительной информации я не думаю, что смогу вам помочь. Я настоятельно рекомендую отредактировать ваш вопрос, добавив всю информацию, относящуюся к вашей проблеме (например, » static readonly » не упоминается в вашем вопросе). Удачи.