angular - Diferența dintre interfețe și clase în Typescript


Care este diferența dintre interfețele și clasele din Typescript? Când folosesc o clasă? Când folosesc interfețe? Care sunt avantajele lor?

Trebuie să creez un fel de tipuri pentru un request HTTP către serverul meu backend (Facând asta cu Angular 2), de genul : },

"fields": {
  "project": {
      "id": "10000"
  },
  "summary": "something's wrong",
  "issuetype": {
      "id": "10000"
  },
  "assignee": {             // not neccesary required
      "name": "homer"
  },
  "reporter": {
      "name": "smithers"
  },
  "priority": {            // not neccesary required
      "id": "20000"
  }
}

Ce ar trebui să folosesc pentru a construi aceste modele? Mulțumesc!

Răspuns #1

2019: Actualizare privind diferențele și utilizările

Mai întâi, există diferența evidentă: syntaxa. Aceasta este o diferență simplă, dar necesară pentru a fi înțeleasă: Proprietățile unei interfețe pot să se încheie cu virgule sau punct și virgulă, însă proprietățile unei clase se pot încheia doar cu punct și virgulă. Acum partea interesantă. Secțiunile despre când să folosești și când să nu folosești pot fi subiective - acestea sunt liniile directoare pe care le dau persoanelor din echipa mea, dar este posibil ca alte echipe să aibă alte linii directoare din motive valide. Simțiți-vă liber să comentați dacă echipa voastră o face diferit, mi-ar plăcea să aflu de ce.

Interfețe: Permit definirea unui tip care va fi utilizat în timpul proiectării și al compilării pentru tipizare strictă. Ele pot fi „implementate” sau „extinse”, dar nu pot fi instanțiate (nu poți să le new). Acestea sunt eliminate atunci când se transpilează în JS, deci nu ocupă spațiu, dar, de asemenea, nu pot fi verificate tipologic în timpul rulării, astfel că nu poți verifica dacă o variabilă implementează un anumit tip la runtime (de exemplu, foo instanceof bar), decât prin verificarea proprietăților pe care le are: Verificarea tipului de interfață cu Typescript.

Când să folosești interfețele: Folosește-le atunci când trebuie să creezi un contract al proprietăților și funcțiilor pentru un obiect care va fi utilizat în mai multe locuri din codul tău, în special în mai multe fișiere sau funcții. De asemenea, folosește-le atunci când vrei ca alte obiecte să pornească cu acest set de proprietăți de bază, cum ar fi să ai o interfață Vehicle pe care mai multe clase să o implementeze ca tipuri specifice de vehicule, cum ar fi Car, Truck, Boat (de exemplu class Car implements Vehicle).

Când să nu folosești interfețe: Atunci când vrei să ai valori implicite, implementări, constructori sau funcții (nu doar semnături).

Clase: De asemenea, permit definirea unui tip care va fi folosit în timpul design-ului și al compilării pentru tipare forte și, în plus, poate fi folosit și în timpul execuției. Aceasta înseamnă, de asemenea, că codul nu este eliminat la compilare, deci va ocupa spațiu. Aceasta este o diferență cheie menționată de @Sakuto, dar are mai multe implicații decât simpla ocupare de spațiu. Înseamnă că clasele pot fi verificate din punct de vedere al tipului, păstrând înțelegerea „cine sunt ele” chiar și în codul JS transpilat. Alte diferențe includ: clasele pot fi instanțiate folosind new și pot fi extinse, dar nu implementate. Clasele pot avea constructori și cod efectiv al funcțiilor, împreună cu valori implicite.

Când să folosești clase: Când vrei să creezi obiecte care au cod de funcție propriu, au un constructor pentru inițializare și/sau vrei să creezi instanțe ale acestora cu new. De asemenea, pentru obiectele de date simple, poți folosi clase pentru a seta valorile implicite. Un alt moment în care ai dori să le folosești este atunci când faci verificări de tip, deși există soluții alternative pentru interfețe dacă este necesar (vezi secțiunea despre interfețe OS link).

Când să nu folosești clase: Atunci când ai o interfață de date simplă, nu ai nevoie să o instanțiezi, când vrei să fie implementată de alte obiecte, când vrei pur și simplu să pui o interfață pe un obiect existent (gândește-te la fișierele de definiție tip) sau când spațiul pe care l-ar ocupa este prohibitiv sau nejustificat. Ca o notă suplimentară, dacă te uiți în fișierele .d.ts vei observa că acestea folosesc doar interfețe și tipuri, și astfel acest lucru este complet eliminat atunci când este transpilat în JavaScript.

Notă finală, există două alte opțiuni în afară de clase și interfețe, prima este ceva numit „type”, care este destul de similar cu o interfață, dar verifică acest post de pe SO, în special răspunsul actualizat din 2019: Interfețe vs Tipuri în TypeScript. Ultima opțiune este să folosești stilul de programare funcțională (nu OOP) cu TS.

Pentru povestea completă cu exemple vizitați PassionForDev.com și pentru mai multe lecturi bune despre clase vs. moștenire cu exemple vizitați https://jameshenry.blog/typescript-classes-vs-interfaces/.

Răspunsul #2

Conform ghidului de stil Angular 2, se recomandă utilizarea Class în loc de Interface pentru tipizare. Principala diferență este că class va persista după compilare, în timp ce Interface sunt complet eliminate, deoarece nu au nicio utilitate la rulare.

Doar rămâi consecvent pe tot parcursul proiectului și preferă abordarea ghidului de stil cu class, cine știe, poate într-o zi va trebui să adaugi method în modelele tale.

Verificați răspunsul de mai jos pentru mai multe detalii: https://stackoverflow.com/a/55505227/5463904

Răspunsul #3

Simplu, Clasa este pentru a crea obiecte, iar Interfața te ajută să știi ce ar trebui să conțină aceste obiecte.

Clasa este ca un plan/schita folosind care putem crea obiecte. Interfața este ca un contract asupra căruia o Clasa trebuie să fie de acord pentru a implementa acea Interfață sau a defini ce ar trebui să conțină această schiță.

O clasă simplă:

class Car {
    engine: string; // 'var' is not used;

    constructor(engine: string) { // This is how we create constructor
        this.engine = engine;
    }

    display(): void { // 'function' keyword is not used here.
        console.log(`Engine is ${this.engine}`); // just a log.
    }
}

var objCar = new Car('V8'); // creates new onject
objCar.display(); // output: Engine is V8
console.log(objCar.engine); // output: V8 (accessing member here)

O interfață simplă:

    interface IPerson { // This is how we create an interface.
        firstName: string, // use commas to separate.
        lastName: string, // In classes we use semi-colon to separate.
        displayDetails: (number) => string
    }

    // We are going to store 'interface object' in a variable.
    // i.e. we are implementing interface with variable(not class!!)
    var customer: IPerson = {

        firstName: 'jose jithin', // 'implements' variables
        lastName: 'stanly',

        // Now method implementation.
        // Note: the syntax of 'displayDetails' maybe a bit confusing (given below)
        // as two colons are used.
        // It specifies a return type(string) here for this method. 
        displayDetails: (rank): string => { return `This person has rank ${rank}. ` }  

        // It can be rewritten as following too.
        displayDetails: (rank) => { return `This person has rank ${rank}. ` };
        // i.e. return type need not be specified, just like a normal method definition syntax.
    }

    console.log(customer.firstName); // output: jose jithin

    console.log(customer.lastName);  // output: stanly

    console.log(customer.displayDetails(1)); // output: This person has rank 

Am detaliat despre Clasă și Interfață în articolul meu. Acest lucru te-ar putea ajuta să înțelegi.