Что использовать для объектов только для данных в 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 );