Interfejsy mają zerowy wpływ runtime JS. W interfejsach TypeScript jest dużo mocy do deklarowania struktury zmiennych.
Następujące dwie są równoważnymi deklaracjami, pierwsza używa adnotacji inline, druga używa interfejsu:
// Sample Adeclare var myPoint: { x: number; y: number; };// Sample Binterface Point {x: number; y: number;}declare var myPoint: Point;
Jednakże piękno Sample B polega na tym, że jeśli ktoś napisze bibliotekę, która opiera się na bibliotece myPoint
, aby dodać nowych członków, może łatwo dodać do istniejącej deklaracji 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!
To dlatego, że interfejsy w TypeScript są otwarte. Jest to istotne założenie TypeScript, które pozwala naśladować rozszerzalność JavaScript za pomocą interfejsów.
Klasy mogą implementować interfejsy
Jeśli chcesz używać klas, które muszą podążać za strukturą obiektu, którą ktoś zadeklarował dla ciebie w interface
, możesz użyć słowa kluczowego implements
, aby zapewnić kompatybilność:
interface Point {x: number; y: number;}class MyPoint implements Point {x: number; y: number; // Same as Point}
Podstawowo w obecności tego implements
, wszelkie zmiany w tym zewnętrznym interfejsie Point
spowodują błąd kompilacji w twojej bazie kodu, więc możesz łatwo utrzymać go w synchronizacji:
interface Point {x: number; y: number;z: number; // New member}class MyPoint implements Point { // ERROR : missing member `z`x: number; y: number;}
Zauważ, że implements
ogranicza strukturę instancji klasy i.e.:
var foo: Point = new MyPoint();
I rzeczy takie jak foo: Point = MyPoint
to nie to samo.
Nie każdy interfejs jest implementowalny łatwo
Interfejsy są zaprojektowane do deklarowania dowolnej arbitralnie zwariowanej struktury, która może być obecna w JavaScript.
Rozważmy następujący interfejs, gdzie coś jest wywoływalne za pomocą new
:
interface Crazy {new (): {hello: number};}
Miałbyś zasadniczo coś takiego:
class CrazyClass implements Crazy {constructor() {return { hello: 123 };}}// Becauseconst crazy = new CrazyClass(); // crazy would be {hello:123}
Możesz zadeklarować wszystkie szalone JS tam z interfejsami, a nawet używać ich bezpiecznie z TypeScript. Nie oznacza to jednak, że możesz używać klas TypeScript do ich implementacji.