Heim > Web-Frontend > js-Tutorial > Detaillierte Erläuterung der Schnittstellen in TypeScript_Javascript-Kenntnissen

Detaillierte Erläuterung der Schnittstellen in TypeScript_Javascript-Kenntnissen

WBOY
Freigeben: 2016-05-16 15:54:07
Original
1545 Leute haben es durchsucht

In TypeScript werden Schnittstellen als Einschränkungen verwendet. Beim Kompilieren in JavaScript werden alle Schnittstellen gelöscht, da es in JavaScript kein Schnittstellenkonzept gibt.

Sehen wir uns ein einfaches Beispiel an:

function printLabel(labelledObj: { label: string }) {
  console.log(labelledObj.label);
}

var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

Nach dem Login kopieren

Dann ist in dieser Methode der Typ von labeledObj {label: string}, was etwas kompliziert erscheinen mag, aber wenn wir uns die Deklaration von myObj unten ansehen, werden wir wissen, dass es sich um eine Deklaration mit einem Größenattribut handelt ( Wert ist 10) und ein Objekt mit einem Label-Attribut (Wert „Size 10 Object“). Daher ist der Typ des Methodenparameters labeledObj {label: string}, was bedeutet, dass der Parameter ein Label-Attribut vom Typ string hat.

Allerdings erscheint diese Methode, so geschrieben, immer noch etwas verwirrend. Anschließend können Sie eine Schnittstelle verwenden, um den Parametertyp dieser Methode zu definieren.

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

Nach dem Login kopieren

Optionale Attribute
Manchmal muss das Attribut nicht vorhanden sein, daher können wir das optionale Attribut verwenden, um es zu definieren.

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
  var newSquare = { color: "white", area: 100 };
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

var mySquare = createSquare({ color: "black" });

Nach dem Login kopieren

Dann übergeben wir ein Objekt, das eine SquareConfig-Schnittstelle implementiert, in die Methode createSquare.

Da es völlig entbehrlich ist, warum müssen wir es dann definieren? Das Definieren optionaler Eigenschaften hat zwei Vorteile gegenüber dem Verzicht darauf, sie überhaupt zu definieren. 1. Wenn Attribute vorhanden sind, kann der Typ eingeschränkt werden, was sehr wichtig ist. 2. Sie können intelligente Syntax-Eingabeaufforderungen erhalten. Wenn Sie Farbe fälschlicherweise als collor in den Methodenkörper schreiben, wird die Kompilierung nicht erfolgreich sein.

Methodentyp

In JavaScript ist die Methodenfunktion ein Grundtyp. Im objektorientierten Denken erfolgt die Implementierung von Schnittstellen durch Klassen. Kann eine Funktion als Typ Schnittstellen implementieren? Die Antwort ist ja.

In TypeScript können wir Schnittstellen verwenden, um Methodensignaturen einzuschränken.

interface SearchFunc {
 (source: string, subString: string): boolean;
}

var mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
 var result = source.search(subString);
 if (result == -1) {
  return false;
 }
 else {
  return true;
 }
}

Nach dem Login kopieren

Im obigen Code definieren wir eine Schnittstelle, die die Signatur einer Methode einschränkt. Diese Methode hat zwei String-Parameter und gibt einen booleschen Wert zurück. Im zweiten Codeteil deklarieren wir die Implementierung dieser Schnittstelle.

Es ist zu beachten, dass der Compiler nur prüft, ob der Typ korrekt ist (Parametertyp, Rückgabewerttyp), sodass wir den Parameternamen in einen anderen Namen ändern können.

var mySearch: SearchFunc;
mySearch = function(src: string, sub: string) {
 var result = src.search(sub);
 if (result == -1) {
  return false;
 }
 else {
  return true;
 }
}
Nach dem Login kopieren

Dies kann auch kompiliert und übergeben werden.

Array-Typ
Oben haben wir den Methodentyp in der Schnittstelle definiert. Wie sollte also der Array-Typ definiert werden? Ganz einfach.

interface StringArray {
 [index: number]: string;
}

var myArray: StringArray;
myArray = ["Bob", "Fred"];

Nach dem Login kopieren

Dann ist myArray ein Array, der Indexer ist vom Typ Zahl und die Elemente sind Zeichenfolgen.

In der Definition der Schnittstelle ist der Name des Indexers im Allgemeinen Index (natürlich kann er in etwas anderes geändert werden, aber im Allgemeinen wird der Name als Index beibehalten). Ändern Sie es also in

interface StringArray {
 [myIndex: number]: string;
}

var myArray: StringArray;
myArray = ["Bob", "Fred"];

Nach dem Login kopieren

Auch ok.

Es ist zu beachten, dass der Typ des Indexers nur eine Zahl oder eine Zeichenfolge sein kann.

interface Array{
  [index: number]: any;
}

interface Dictionary{
  [index: string]: any;
}

Nach dem Login kopieren

Die beiden oben genannten Absätze können zusammengestellt und weitergegeben werden.

Als letztes ist zu beachten, dass, wenn die Schnittstelle bereits ein Array-Typ ist, die Typen anderer in der Schnittstelle definierter Attribute der Elementtyp des Arrays sein müssen. Zum Beispiel:

interface Dictionary {
 [index: string]: string;
 length: number;  // error, the type of 'length' is not a subtype of the indexer
}
Nach dem Login kopieren

Dann wird es nicht kompiliert und die Länge muss in den String-Typ geändert werden.

Verwenden Sie Klassen, um Schnittstellen zu implementieren
Unter normalen Umständen sind wir es immer noch gewohnt, eine Klasse zum Implementieren der erforderlichen Schnittstelle zu verwenden, anstatt die Schnittstelle wie oben direkt zu verwenden.

interface ClockInterface {
  currentTime: Date;
}

class Clock implements ClockInterface {
  currentTime: Date;
  constructor(h: number, m: number) { }
}

Nach dem Login kopieren

In TypeScript wird zum Deklarieren das Schlüsselwort class verwendet, das mit EcmaScript 6 identisch ist.

Darüber hinaus können wir Schnittstellen verwenden, um die in der Klasse definierten Methoden einzuschränken.

interface ClockInterface {
  currentTime: Date;
  setTime(d: Date);
}

class Clock implements ClockInterface {
  currentTime: Date;
  setTime(d: Date) {
    this.currentTime = d;
  }
  constructor(h: number, m: number) { }
}

Nach dem Login kopieren

In TypeScript können wir Konstruktoren für Schnittstellen definieren.

interface ClockInterface {
  new (hour: number, minute: number);
}
Nach dem Login kopieren

Wenn wir naiv sind, könnten wir so schreiben:

interface ClockInterface {
  new (hour: number, minute: number);
}

class Clock implements ClockInterface {
  currentTime: Date;
  constructor(h: number, m: number) { }
}

Nach dem Login kopieren

Das wird nicht funktionieren! ! ! Da der Konstruktor statisch ist, kann die Klasse nur den Instanzteil der Schnittstelle implementieren.

Dann hat der in dieser Schnittstelle definierte Konstruktor keine Wirkung? Da TypeScript diese Funktionalität bereitstellt, ist es definitiv nicht nutzlos. Die deklarierte Methode ist etwas ganz Besonderes:

interface ClockStatic {
  new (hour: number, minute: number);
}

class Clock {
  currentTime: Date;
  constructor(h: number, m: number) { }
}

var cs: ClockStatic = Clock;
var newClock = new cs(7, 30);

Nach dem Login kopieren

Normalerweise schreiben wir neue Clock, hier verweisen wir die Clock-Klasse auf die ClockStatic-Schnittstelle. Es ist zu beachten, dass der Typ der newClock-Variable beliebig ist.

Geerbte Schnittstelle
Wie Klassen können auch Schnittstellen mithilfe des Schlüsselworts „extens“ eine Vererbung implementieren.

interface Shape {
  color: string;
}

interface Square extends Shape {
  sideLength: number;
}

var square = <Square>{};
square.color = "blue";
square.sideLength = 10;

Nach dem Login kopieren

Natürlich können auch mehrere Schnittstellen vererbt werden.

interface Shape {
  color: string;
}

interface PenStroke {
  penWidth: number;
}

interface Square extends Shape, PenStroke {
  sideLength: number;
}

var square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

Nach dem Login kopieren

Es ist zu beachten, dass die Kompilierung nicht erfolgreich ist, obwohl das Erben mehrerer Schnittstellen unterstützt wird. Wenn jedoch die in den geerbten Schnittstellen definierten Typen von Eigenschaften mit demselben Namen unterschiedlich sind, wird die Kompilierung nicht erfolgreich sein.

interface Shape {
  color: string;
  test: number;
}

interface PenStroke {
  penWidth: number;
  test: string;
}

interface Square extends Shape, PenStroke {
  sideLength: number;
}

Nach dem Login kopieren

那么这段代码就无法编译通过了,因为 test 属性的类型无法确定。

同时使用上面所述的类型
如果仅能单一使用某种类型,那么这接口也未免太弱了。但幸运的是,我们的接口很强大。

interface Counter {
  (start: number): string;
  interval: number;
  reset(): void;
}

var c: Counter;
c(10);
c.reset();
c.interval = 5.0;

Nach dem Login kopieren

这样就使用到三种类型了,分别是方法(接口自己是个方法)、属性、方法(定义了方法成员)。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage