Le interfacce hanno un impatto JS a runtime zero. C’è molto potere nelle interfacce TypeScript per dichiarare la struttura delle variabili.
Le due seguenti sono dichiarazioni equivalenti, la prima usa un’annotazione inline, la seconda un’interfaccia:
// Sample Adeclare var myPoint: { x: number; y: number; };// Sample Binterface Point {x: number; y: number;}declare var myPoint: Point;
Tuttavia, la bellezza del Sample B è che se qualcuno scrive una libreria che si basa sulla libreria myPoint
per aggiungere nuovi membri, può facilmente aggiungere alla dichiarazione esistente di myPoint
:
// Lib a.d.tsinterface Point {x: number; y: number;}declare var myPoint: Point;// Lib b.d.tsinterface Point {z: number;}// Your codevar myPoint.z; // Allowed!
Questo perché le interfacce in TypeScript sono aperte. Questo è un principio vitale di TypeScript che permette di imitare l’estensibilità di JavaScript usando le interfacce.
Le classi possono implementare interfacce
Se vuoi usare classi che devono seguire una struttura di oggetti che qualcuno ha dichiarato per te in un interface
puoi usare la parola chiave implements
per assicurare la compatibilità:
interface Point {x: number; y: number;}class MyPoint implements Point {x: number; y: number; // Same as Point}
Fondamentalmente in presenza di quel implements
, qualsiasi cambiamento in quell’interfaccia esterna Point
risulterà in un errore di compilazione nel vostro codice base in modo da poterlo mantenere facilmente sincronizzato:
interface Point {x: number; y: number;z: number; // New member}class MyPoint implements Point { // ERROR : missing member `z`x: number; y: number;}
Nota che implements
limita la struttura delle istanze della classe i.e.:
var foo: Point = new MyPoint();
E roba come foo: Point = MyPoint
non è la stessa cosa.
Non ogni interfaccia è implementabile facilmente
Le interfacce sono progettate per dichiarare qualsiasi struttura arbitrariamente folle che potrebbe essere presente in JavaScript.
Considera la seguente interfaccia dove qualcosa è richiamabile con new
:
interface Crazy {new (): {hello: number};}
Essenzialmente avresti qualcosa come:
class CrazyClass implements Crazy {constructor() {return { hello: 123 };}}// Becauseconst crazy = new CrazyClass(); // crazy would be {hello:123}
Puoi dichiarare tutto il pazzo JS là fuori con le interfacce e anche usarle in modo sicuro da TypeScript. Non significa che puoi usare le classi TypeScript per implementarle.
class CrazyClass implements Crazy {constructor() {return { hello: 123 };}}// Becauseconst crazy = new CrazyClass(); // crazy would be {hello:123}
Si può dichiarare tutto il folle JS con le interfacce e usarle in modo sicuro da TypeScript.