Что использовать для объектов только для данных в TypeScript: класс или интерфейс?

У меня есть куча только классов данных (в мире .NET мы называем их объектами POCO), у которых нет каких-либо методов или даже конструкторов. Примерами являются Customer, Product, User entity, вы называете это...

Первоначально я начал использовать классы typescript, но теперь я думаю, что объявление их как интерфейса может быть лучше. С точки зрения производительности, и не только... Это просто, что в С# мы привыкли использовать интерфейсы для разных вещей, а для объекта "POCO" (Plain-old-clr-object или "только для данных" ) мы используем просто класс (иногда даже структура).

Каков правильный способ объявить их в TypeScript?

Обратите внимание, что я в основном понимаю (я думаю) технические различия между классом и интерфейсом (т.е. этот интерфейс является конструкцией времени компиляции), но я пытаюсь выяснить, какой из них подходит семантически.

PS: Я видел похожие вопросы (например, this), но никто из них не ясно и однозначно не конкретизирует эту конкретную проблему, поэтому, пожалуйста, не закрывайте это как "возможно дублировать" или "основанное на мнениях" (потому что это не так):)

Ответы

Ответ 1

Интерфейс и он даже не закрывается.

Люди начинают писать TypeScript, и они вдруг думают, что по какой-то причине они должны использовать классы. Но они этого не делают. Классы - это функция ES6, и они работают нормально, но если это просто данные, это просто данные.

Основная проблема с использованием классов заключается в том, что они не будут сериализоваться/десериализоваться, как вы ожидаете, за провод, поэтому такие вещи, как instanceof, не будут работать.

Одно эмпирическое правило состоит в том, что если не существует внутреннего состояния, связанного с некоторыми методами, и нет необходимости в традиционном полиморфизме ОО, не используйте класс. Это даже распространяется на static class es - вместо этого используйте namespace/module.

Ответ 2

Я использую классы для своих данных в Typescript, как я всегда делал в С# С++ Java, и использую только интерфейсы для инъекции зависимостей. Интерфейсы не предназначены для управления данными.

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

Я не программист javascript, поэтому, когда мне нужно создать объект, мне не нравится использовать объект данных, где свойства могут быть чем угодно. Я создаю экземпляр класса с помощью конструкторов, которые были определены для этого класса.

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

// ajax callback for diaries
onReceiveDiary( jsonDiary : any )
{
   let newDiary = new Diary ( jsonDiary );

   // now I can call methods on the object:
   let ok : boolean = newDiary.CheckIfCompleted();
}

В классе я добавляю конструктор с единственной зависимостью от объекта json:

export class Diary
{
   title : string;
   article : Article;

   constructor( json : any )
   {
      // the trick for setting all the object properties
      $.extend( this, json);

      this.article = new Article( json.article );
   }
}

Или мы можем создать factory для создания объектов с помощью конструктора по умолчанию:

   let newDiary = new Diary ();
   $.extend( newDiary, jsonDiary );
   newDiary.article = $.extend( new Article(), jsonDiary.article );