Kiedy używać interfejsu i modelu w TypeScript / Angular2

197

Niedawno obejrzałem samouczek na temat Angulara 2 z TypeScript, ale nie jestem pewien, kiedy użyć interfejsu, a kiedy modelu do przechowywania struktur danych.

Przykład interfejsu:

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

Przykład modelu:

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

Chcę załadować dane JSON z adresu URL i powiązać z interfejsem / modelem. Czasami chcę pojedynczy obiekt danych, innym razem chcę trzymać i tablicę obiektu.

Którego powinienem użyć i dlaczego?

I_LIKE_FOO
źródło
13
Użyj klasy, gdy potrzebujesz niestandardowej inicjalizacji logicznej, w przeciwnym razie zawsze używaj interfejsu, ponieważ jest on dostępny tylko podczas kompilacji. Interfejs maszynopisu nie jest kompilowany do javascript, ponieważ nie istnieje w javascript.
Dieterg
6
Pamiętaj, że interfejsy NIE będą działać z wstrzykiwaniem zależności w Angular 2. Tutaj będziesz musiał użyć klas.
jlang

Odpowiedzi:

137

Interfejsy są dostępne tylko podczas kompilacji. Pozwala to tylko na sprawdzenie, czy oczekiwane dane mają określoną strukturę. W tym celu możesz przesłać zawartość do tego interfejsu:

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

Zobacz te pytania:

Możesz zrobić coś podobnego z klasą, ale główne różnice z klasami polegają na tym, że są one obecne w środowisku uruchomieniowym (funkcja konstruktora) i możesz definiować w nich metody podczas przetwarzania. Ale w tym przypadku musisz utworzyć instancję obiektów, aby móc z nich korzystać:

this.http.get('...')
    .map(res => {
      var data = res.json();
      return data.map(d => {
        return new Product(d.productNumber,
          d.productName, d.productDescription);
      });
    });
Thierry Templier
źródło
27
Dziękuję za szczegółową odpowiedź. Jeśli interfejs jest używany tylko w czasie kompilacji, w jaki sposób kompilator może sprawdzić strukturę pliku JSON bez faktycznego sprawdzania http get? Jeśli nie, to po co w ogóle zawracać sobie głowę interfejsem?
I_LIKE_FOO
7
@I_LIKE_FOO kompilator nie musi sprawdzać wywołania get. Dba tylko o sprawdzenie typów, o których wie i czy są prawidłowo wyrównane. var data = res.json();jest naprawdę var data: any = res.json();dla kompilatora, więc tracimy sprawdzanie wszystkich typów data. Jaki byłby bardziej przydatny byłby tu coś var data: ProductDto[] = res.json();z ProductDtoczym interfejs, który modeluje strukturę danych w zwróconym JSON.
GFoley83
3
Więcej informacji: Angular style guide says not to use interfaces.Always use classes.patrz angular.io/guide/styleguide#style-03-03
Sampath,
4
Tak, ale problem polega na tym, że nie są to bogowie guru, którzy opracowali maszynopis. To byłby Microsoft i firma. Zwykle faworyzują interfejsy i klasy, gdy jest to właściwe. Również punkty bonusowe ... jeden to środowisko uruchomieniowe, a drugi jest w czasie kompilacji
Tom Stickel
11
@Sampath Być może przewodnik po stylu Angular został zaktualizowany, ponieważ teraz widzę to „Rozważ zastosowanie interfejsu dla modeli danych”. Implikuje preferowanie interfejsu nad klasą dla modeli danych.
Mikezx6r
40

Interfejs opisuje albo umowę na klasy lub nowego typu . Jest to czysty element Typescript, więc nie wpływa na Javascript.

Model, a mianowicie klasa , jest faktyczną funkcją JS używaną do generowania nowych obiektów.

Chcę załadować dane JSON z adresu URL i powiązać z interfejsem / modelem.

Wybierz model, w przeciwnym razie w JavaScript będzie nadal JSON.

pietro909
źródło
4

Jak powiedział @ThierryTemplier do odbierania danych z serwera, a także do przesyłania modelu między komponentami (aby zachować listę intellisense i popełnić błąd czasu projektowania), dobrze jest użyć interfejsu, ale myślę, że do wysyłania danych na serwer (DTO) lepiej jest użyć klasy, aby wziąć zalety automatycznego mapowania DTO z modelu.

M_Farahmand
źródło
-22

Użyj klasy zamiast interfejsu , co odkryłem po wszystkich moich badaniach.

Czemu? Sama klasa to mniej kodu niż interfejs klasy plus. (w każdym razie możesz wymagać klasy dla modelu danych)

Czemu? Klasa może działać jako interfejs (użyj narzędzi zamiast rozszerzeń).

Czemu? Klasa interfejsu może być tokenem wyszukiwania dostawcy we wstrzykiwaniu zależności kątowej.

z Angular Style Guide

Zasadniczo klasa może zrobić wszystko, co zrobi interfejs. Dlatego może nigdy nie będzie konieczne użycie interfejsu .

Sajith Mantharath
źródło
10
Przewodnik po stylu Angular aktualnie mówi: „ Rozważ zastosowanie interfejsu dla modeli danych.
Alex Peters,
@AlexPeters Podaj dowolny autentyczny link. Z góry dziękuję
Anand Phadke
@AnandPhadke, na pewno, oto link do Wayback Machine do Angular Style Guide z czasów mojego komentarza powyżej.
Alex Peters