Недавно я смотрел Учебник по 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-адреса и привязать к интерфейсу / модели. Иногда мне нужен единственный объект данных, а иногда я хочу хранить массив этого объекта.

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

Ответы (6)

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

this.http.get('...')
    .map(res => res.json());

См. Эти вопросы:

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

this.http.get('...')
    .map(res => {
      var data = res.json();
      return data.map(d => {
        return new Product(d.productNumber,
          d.productName, d.productDescription);
      });
    });

Я лично использую интерфейсы для своих моделей. По этому вопросу существует 3 школы, и выбор одной из них чаще всего зависит от ваших требований:

1- Интерфейсы:

interface is a virtual structure that only exists within the context of TypeScript. The TypeScript compiler uses interfaces solely for type-checking purposes. Once your code is transpiled to its target language, it will be stripped from its interfaces - JavaScript isn’t typed.

Пользователь интерфейса {
 идентификационный номер;
 имя пользователя: строка;
}
// наследование
интерфейс UserDetails расширяет User {
 дата рождения: Дата;
 биография ?: строка; // использовать '?' аннотация, чтобы пометить это свойство как необязательное
}

Ответ сервера сопоставления на интерфейс прост, если вы используете HttpClient из HttpClientModule, если вы используете Angular 4.3.x и выше.

getUsers (): Observable  {
 вернуть this.http.get  (url); // нет необходимости в '.map ((res: Response) => res.json ())'
}

когда использовать интерфейсы:

  • Вам нужно только определение данных сервера без дополнительных накладных расходов для окончательного вывода.
  • Вам нужно только передавать данные без какого-либо поведения или логики (инициализация конструктора, методы)
  • Вы не очень часто инстанцируете / создаете объекты из своего интерфейса
    • Используя простую объектно-буквальную нотациюlet instance: FooInterface = {...};, вы рискуете повсюду иметь полуэкземпляры.
    • Это не обеспечивает соблюдения ограничений, заданных классом (конструктор или логика инициализации, проверка, инкапсуляция частных полей ... и т. Д.)
  • Вам необходимо определить контракты / конфигурации для ваших систем (глобальные конфигурации)

2- Классы:

A class определяет чертежи объекта. Они выражают логику, методы и свойства, которые будут унаследованы этими объектами.

класс Пользователь {
 идентификационный номер;
 имя пользователя: строка;
 конструктор (id: число, имя пользователя: строка) {
  this.id = id;
  this.username = имя пользователя.replace (/ ^ \ s + | \ s + $ / g, ''); // обрезка пробелов и новых строк
 }
}
// наследование
class UserDetails расширяет User {
 дата рождения: Дата;
 биография ?: строка;
 конструктор (id: номер, имя пользователя: строка, дата рождения: дата, биография?: строка) {
   super (id, имя пользователя);
  this.birthdate = ...;
 }
}

когда использовать классы:

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

2- Типы:

С последними версиями машинописного текста интерфейсы и типы становятся все более похожими. типы не выражают логику или состояние внутри вашего приложения. Лучше всего использовать типы, когда вы хотите описать какую-либо форму информации. Они могут описывать различные формы данных, начиная от простых конструкций, таких как строки, массивы и объекты. Как и интерфейсы, типы - это всего лишь виртуальные структуры, которые не переносятся на какой-либо javascript, они просто помогают компилятору облегчить нашу жизнь.

введите User = {
 идентификационный номер;
 имя пользователя: строка;
}
// наследование
type UserDetails = User & {
  Дата рождения: Дата;
  биография?: строка;
}

когда использовать типы:

  • передать его как краткие параметры функции
  • описать параметры конструктора класса
  • документировать небольшие или средние объекты, поступающие или исходящие из API.
  • они не несут ни состояние, ни поведение

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

Чтобы сделать ваш код гибким, нам нужно использовать интерфейсы. Создайте интерфейсы и передайте тип интерфейса в конструктор класса. Здесь используется внедрение зависимостей.

Льготы:

  1. Если есть изменение в параметрах интерфейса, менять класс не нужно. 2. Для тестирования в конструкторе класса можно использовать фиктивные данные.

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

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

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

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

Использовать класс вместо интерфейса - вот что я обнаружил после всех своих исследований.

Why? A class alone is less code than a class-plus-interface. (anyway you may require a Class for data model)

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

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

из Руководства по стилю Angular

Basically a Class can do all, what an Interface will do. So may never need to use an Interface.

2022 WebDevInsider