Когда использовать интерфейс и модель в TypeScript / Angular2

198

Недавно я смотрел Учебник по Angular 2 с TypeScript, но не знал, когда использовать Интерфейс, а когда использовать Модель для хранения структур данных.

Пример интерфейса:

export interface IProduct {
    ProductNumber: number;
    ProductName: string;
    ProductDescription: string;
}

Пример модели:

export class Product {
    constructor(
        public ProductNumber: number,
        public ProductName: string,
        public ProductDescription: string
    ){}
}

Я хочу загрузить данные JSON из URL и привязать к интерфейсу / модели. Иногда я хочу один объект данных, в другой раз я хочу держать и массив объекта.

Какой из них я должен использовать и почему?

I_LIKE_FOO
источник
14
Используйте класс, когда вам нужна пользовательская логика init, в противном случае всегда используйте интерфейс, так как он доступен только во время компиляции. Интерфейс машинописи не скомпилирован в javascript, так как он не существует в javascript.
Дитерг
6
Имейте в виду, что интерфейсы НЕ будут работать с внедрением зависимостей в Angular 2. Здесь вам придется использовать классы.
Jlang

Ответы:

138

Интерфейсы только во время компиляции. Это позволяет только вам убедиться, что ожидаемые полученные данные соответствуют определенной структуре. Для этого вы можете привести свой контент к этому интерфейсу:

this.http.get('...')
    .map(res => <Product[]>res.json());

Смотрите эти вопросы:

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

this.http.get('...')
    .map(res => {
      var data = res.json();
      return data.map(d => {
        return new Product(d.productNumber,
          d.productName, d.productDescription);
      });
    });
Тьерри Темплиер
источник
27
Спасибо за ваш подробный ответ. Если интерфейс используется только во время компиляции, как компилятор может проверить структуру файла JSON без фактического изучения http get? Если это невозможно, то какой смысл вообще беспокоиться об интерфейсе?
I_LIKE_FOO
7
@I_LIKE_FOO компилятору не нужно проверять вызов get. Он заботится только о проверке типов, о которых он знает, и о том, что они правильно выровнены. var data = res.json();действительно var data: any = res.json();для компилятора, поэтому мы теряем все проверки типов data. Что полезнее было бы здесь было бы что - то вроде var data: ProductDto[] = res.json();с ProductDtoтем интерфейсом , который моделирует структуру данных в возвращаемом JSON.
GFoley83
3
Подробнее: Angular style guide says not to use interfaces.Always use classes.см. Angular.io/guide/styleguide#style-03-03
Sampath
4
Да, но проблема в том, что они не боги гуру, которые создали Typescript. Это будет Microsoft и компания. Они предпочитают интерфейсы и классы, когда это уместно. Также бонусные баллы ... один - во время выполнения, а другой - во время компиляции
Том Стиккель
11
@Sampath Возможно, руководство по стилю Angular было обновлено, так как теперь я вижу это «Рассмотрите возможность использования интерфейса для моделей данных». Подразумевает, предпочитают интерфейс над классом для моделей данных.
Mikezx6r
40

Интерфейс описывает либо контракт на класс или новый тип . Это чистый элемент Typescript, поэтому он не влияет на Javascript.

Модель, а именно класс , является реальной JS-функцией, которая используется для генерации новых объектов.

Я хочу загрузить данные JSON из URL и привязать к интерфейсу / модели.

Выберите модель, в противном случае это будет JSON в вашем Javascript.

pietro909
источник
4

Как сказал @ThierryTemplier, для получения данных с сервера, а также для передачи модели между компонентами (для сохранения списка intellisense и для ошибки времени проектирования) хорошо использовать интерфейс, но я думаю, что для отправки данных на сервер (DTO) лучше использовать класс для принятия Преимущества автокартирования DTO от модели.

M_Farahmand
источник
-22

Используйте Class вместо Interface , это то, что я обнаружил после всех моих исследований.

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

Зачем? Класс может действовать как интерфейс (использовать реализации вместо расширений).

Зачем? Интерфейсный класс может быть маркером поиска поставщика в внедрении зависимостей Angular.

из углового руководства по стилю

По сути, класс может делать все, что будет делать интерфейс. Поэтому, возможно, никогда не потребуется использовать интерфейс .

Саджит Мантхарат
источник
10
В настоящее время в Angular Style Guide фактически говорится: « Подумайте об использовании интерфейса для моделей данных.
Алекс Питерс
@AlexPeters Пожалуйста, предоставьте любую подлинную ссылку. Заранее спасибо
Ананд Пхадке
@ AnandPhadke, конечно, вот ссылка Wayback Machine на руководство по угловым стилям со времени моего комментария выше.
Алекс Питерс