Care este diferența dintre „declare class” și „interface” în TypeScript
În TypeScript, atunci când se creează fișiere sursă de declarații .d.ts, care este de preferat și de ce?
declare class Example {
public Method(): void;
}
sau
interface Example {
Method(): void;
}
Diferențele pe care le pot observa sunt că interfețele nu pot avea metode statice, așa că trebuie să folosești o clasă pentru asta. Niciuna dintre ele nu produce vreun output JS, așa că poate că nu contează?
Răspuns #1
interface este folosit atunci când vrei pur și simplu să descrii forma unui obiect. Nu există niciodată generare de cod pentru interfețe -- ele sunt pur și simplu un artefact în sistemul de tipuri. Nu vei vedea nicio diferență în generarea codului pentru o clasă în funcție de faptul că are sau nu o clauză implements.
declare class este folosit atunci când vrei să descrii o clasă existentă (de obicei o clasă TypeScript, dar nu întotdeauna) care va fi prezentă extern (de exemplu, ai două fișiere .ts care se compilează în două fișiere .js și ambele sunt incluse prin taguri script într-o pagină web). Dacă moștenești de la o class folosind extends (indiferent dacă tipul de bază a fost o declare class sau o class obișnuită), compilatorul va genera tot codul pentru a lega lanțul prototipurilor și constructorii de redirecționare și alte lucruri.
Dacă încerci să moștenești de la o declare class care ar fi trebuit să fie o interfață, vei avea o eroare la rulare deoarece codul generat va face referire la un obiect fără manifestare la runtime.
Pe de altă parte, dacă pur și simplu implementezi o interfață care ar fi trebuit să fie o clasă declarată, va trebui să reimplementezi tu însuți toți membrii și nu vei beneficia de nicio reutilizare a codului din clasa de bază potențială, iar funcțiile care verifică lanțul de prototipuri la rulare vor respinge obiectul tău ca nefiind de fapt o instanță a clasei de bază.
Ca să devii cu adevărat geek, dacă ai experiență în C++, poți să te gândești aproximativ la interface ca la typedef și la declare class ca la o declarație extern a unui constructor care lipsește strict cu definiție în această unitate de compilare.
Din perspectiva pur consumativă (scrierea de cod imperativ, fără a adăuga tipuri noi), singura diferență între interface și declare class este că nu poți folosi new pe o interfață. Totuși, dacă intenționezi să extend/implement unul dintre aceste tipuri într-o nouă class, trebuie absolut să alegi corect între interface și declare class. Doar unul dintre ele va funcționa.
Două reguli care te vor ajuta mult:
- Este numele tipului aliniat cu o funcție constructor (ceva ce poate fi invocat cu
new) care este de fapt prezentă la execuție (de exemplu,Dateeste, darJQueryStaticnu este)? Dacă nu, cu siguranță dorițiinterface - Mă ocup de o clasă compilată dintr-un alt fișier TypeScript sau de ceva suficient de similar? Dacă da, folosește
declare class
Răspunsul #2
Puteți implementa interfața:
class MyClass implements Example {
Method() {
}
}
În timp ce sintaxa declare class este cu adevărat destinată să fie folosită pentru a adăuga definiții de tip pentru codul extern care nu este scris în TypeScript - astfel încât implementarea este „în altă parte”.
Răspunsul #3
În termeni simpli, declare este folosit în fișierele .ts/.d.ts pentru a spune compilatorului că trebuie să ne așteptăm ca cuvântul cheie pe care îl declarăm să existe în acel mediu, chiar dacă nu este definit în fișierul prezent. Acest lucru ne va permite apoi să avem siguranță la tipuri când folosim obiectul declarat, deoarece compilatorul Typescript știe acum că un alt component ar putea furniza acea variabilă.
Răspunsul #4
Diferența dintre declare și interface în TS:
declară:
declare class Example {
public Method(): void;
}
În codul de mai sus, declare îi permite compilatorului TS să știe că undeva clasa Example este declarată. Aceasta nu înseamnă că clasa este inclusă magic. Tu, ca programator, ești responsabil să ai clasa disponibilă atunci când o declari (cu cuvântul cheie declare).
interfață:
interface Example {
Method(): void;
}
Un interface este o construcție virtuală care există doar în TypeScript. Compilatorul TypeScript o folosește cu singurul scop de a verifica tipurile. Când codul este compilat în JavaScript, această construcție întreagă va fi eliminată. Compilatorul TypeScript folosește interfețele pentru a verifica dacă obiectele au structura corectă.
De exemplu, atunci când avem următoarea interfață:
interface test {
foo: number,
bar: string,
}
Obiectele pe care le definim și care au acest tip de interfață trebuie să corespundă exact interfeței:
// perfect match has all the properties with the right types, TS compiler will not complain.
const obj1: test = {
foo: 5,
bar: 'hey',
}
