implements în TypeScript

Clase TypeScript 1.0

O clasă promite că respectă una sau mai multe interfețe; tsc verifică dacă are toți membrii ceruți.

Sintaxă
class Nume implements Interfata1, Interfata2 { ... }

Ce face implements

implements leagă o clasă de o interfață: clasa promite că are toate proprietățile și metodele interfeței, cu tipuri compatibile. Dacă lipsește ceva, eroarea apare la declararea clasei, nu mai târziu, când obiectul este folosit.

O clasă poate implementa mai multe interfețe (separate prin virgulă) și poate în același timp să extindă o clasă: class A extends B implements C, D. implements doar verifică; nu copiază nimic din interfață în clasă. Parametrii metodelor nu primesc automat tipurile din interfață, trebuie scriși și în clasă.

Chiar și fără implements, obiectele clasei se potrivesc cu interfața dacă au forma potrivită. Cuvântul este util pentru că documentează intenția și mută eroarea în locul potrivit.

Exemple

Exemplul 1: Două clase, aceeași interfață

interface Notificare {
    destinatar: string;
    trimite(mesaj: string): string;
}

class Email implements Notificare {
    constructor(public destinatar: string) {}
    trimite(mesaj: string): string {
        return `email către ${this.destinatar}: ${mesaj}`;
    }
}

class Sms implements Notificare {
    constructor(public destinatar: string) {}
    trimite(mesaj: string): string {
        return `SMS către ${this.destinatar}: ${mesaj.slice(0, 20)}`;
    }
}

const canale: Notificare[] = [new Email("ana@exemplu.ro"), new Sms("0722000111")];
for (const c of canale) console.log(c.trimite("Nota ta la informatică este 10."));

Rezultat

email către ana@exemplu.ro: Nota ta la informatică este 10.
SMS către 0722000111: Nota ta la informati

Exemplul 2: Metodă lipsă

interface Salvabil {
    salveaza(): void;
    incarca(): void;
}
class Document implements Salvabil {
    salveaza() {
        console.log("salvat");
    }
}
new Document().salveaza();

Eroarea afișată de tsc

exemplu.mts(5,7): error TS2420: Class 'Document' incorrectly implements interface 'Salvabil'.
  Property 'incarca' is missing in type 'Document' but required in type 'Salvabil'.

Exemplul 3: Mai multe interfețe deodată

interface CuNume {
    nume: string;
}
interface Comparabil<T> {
    comparaCu(altul: T): number;
}

class Elev implements CuNume, Comparabil<Elev> {
    constructor(public nume: string, public medie: number) {}
    comparaCu(altul: Elev): number {
        return altul.medie - this.medie;
    }
}

const elevi = [new Elev("Ana", 9.5), new Elev("Mihai", 8.7), new Elev("Ioana", 9.8)];
elevi.sort((a, b) => a.comparaCu(b));
console.log(elevi.map((e) => `${e.nume} ${e.medie}`).join(", "));

Rezultat

Ioana 9.8, Ana 9.5, Mihai 8.7

Greșeli frecvente

  • Crezi că implements dă tipuri parametrilor metodelor. Nu dă: o metodă trimite(mesaj) fără tip are parametrul any (eroare în modul strict).
  • Confunzi implements cu extends. extends moștenește cod de la o clasă; implements doar verifică forma față de o interfață.

Comenzi înrudite

  • interface: Descrie forma unui obiect: ce proprietăți are, de ce tip sunt și ce metode are.
  • extends: O clasă moștenește câmpurile și metodele altei clase; o interfață preia proprietățile altor interfețe.
  • abstract: O clasă abstract nu poate fi instanțiată; metodele abstract trebuie implementate în clasele derivate.
  • class: Clasele din JavaScript, cu tipuri pe câmpuri, constructor și metode, plus modificatori de acces și interfețe.