Funktionsüberladung in TypeScript

Funktionsüberladung in TypeScript

Vorwort:

Die meisten Funktionen akzeptieren einen festen Parametersatz. Einige Funktionen können jedoch eine variable Anzahl von Argumenten oder Argumente unterschiedlichen Typs akzeptieren oder sogar unterschiedliche Typen zurückgeben, je nachdem, wie Sie die Funktion aufrufen. Um solche Funktionen zu kommentieren, bietet TypeScript Funktionsüberladung.

1. Funktionssignatur

Betrachten wir zunächst eine Funktion, die eine Begrüßungsnachricht an eine bestimmte Person zurückgibt.

Funktion Begrüßung (Person: Zeichenfolge): Zeichenfolge {
  returniere `Hallo, ${person}!`;
}


Die obige Funktion akzeptiert ein Argument vom Typ Zeichen: den Namen der Person. Der Aufruf der Funktion ist ganz einfach:

greet('Welt'); // 'Hallo, Welt!'


Was wäre, wenn Sie greet() flexibler gestalten möchten? Beispielsweise können Sie zusätzlich eine Liste mit zu begrüßenden Personen akzeptieren.

Eine solche Funktion akzeptiert einen String oder ein Array von Strings als Argument und gibt einen String oder ein Array von Strings zurück.

Wie kommentiert man eine solche Funktion? Es gibt zwei Methoden.

Der erste Ansatz ist unkompliziert und beinhaltet die direkte Änderung der Funktionssignatur durch Aktualisieren der Parameter und Rückgabetypen.

So sieht greet() nach dem Refactoring aus:

Funktion Begrüßung(Person: Zeichenfolge | Zeichenfolge[]): Zeichenfolge | Zeichenfolge[] {
  wenn (Typ der Person === 'Zeichenfolge') {
    returniere `Hallo, ${person}!`;
  } sonst wenn (Array.isArray(Person)) {
    return person.map(name => `Hallo, ${name}!`);
  }
  neuen Fehler werfen (,,Begrüßung nicht möglich‘);
}


Nun können wir greet() auf zwei Arten aufrufen:

greet('Welt'); // 'Hallo, Welt!'
Grüße (['Xiaozhi', 'Daye']); // ['Hallo, Xiaozhi!', 'Hallo, Daye!']


Es ist ein üblicher und guter Ansatz, die Funktionssignatur direkt zu aktualisieren, um mehrere aufrufende Methoden zu unterstützen.

In einigen Fällen müssen wir jedoch möglicherweise einen anderen Ansatz wählen und alle Möglichkeiten, wie Ihre Funktion aufgerufen werden kann, separat definieren. Dieser Ansatz wird als Funktionsüberladung bezeichnet.

2. Funktionsüberladung

Die zweite Methode besteht in der Verwendung einer Funktionsüberladung. Ich empfehle diesen Ansatz, wenn die Funktionssignatur relativ komplex ist und mehrere Typen umfasst.

Zum Definieren einer Funktionsüberladung müssen eine Überladungssignatur und eine Implementierungssignatur definiert werden.

Eine überladene Signatur definiert die Parameter und den Rückgabetyp der Funktion ohne Funktionskörper. Eine Funktion kann mehrere überladene Signaturen haben: entsprechend unterschiedlichen Möglichkeiten zum Aufrufen der Funktion.

Andererseits verfügt eine Implementierungssignatur auch über Parametertypen und einen Rückgabetyp sowie den Hauptteil der Implementierungsfunktion, und es kann nur eine Implementierungssignatur geben.

// Signaturfunktion überladen greet(person: string): string;
Funktion „Greet“ (Personen: Zeichenfolge []): Zeichenfolge [];
 
// Signaturfunktion implementieren greet(person: unknown): unknown {
  wenn (Typ der Person === 'Zeichenfolge') {
    returniere `Hallo, ${person}!`;
  } sonst wenn (Array.isArray(Person)) {
    return person.map(name => `Hallo, ${name}!`);
  }
  neuen Fehler werfen (,,Begrüßung nicht möglich‘);
}


greet() hat zwei Überladungssignaturen und eine Implementierungssignatur.

Jede Überladungssignatur beschreibt eine Möglichkeit, wie die Funktion aufgerufen werden kann. Was die Funktion greet() betrifft, können wir sie auf zwei Arten aufrufen: mit einem String-Argument oder mit einem String-Array.

Die Implementierungssignaturfunktion function greet(person: unknown): unknown { ... } enthält die entsprechende Logik für die Funktionsweise dieser Funktion.

Jetzt kann greet() wie oben mit einem String oder einem Array von Strings aufgerufen werden.

greet('Welt'); // 'Hallo, Welt!'
Grüße (['Xiaozhi', 'Daye']); // ['Hallo, Xiaozhi!', 'Hallo, Daye!']


2.1 Überladene Signaturen sind aufrufbar

Obwohl die Implementierungssignatur das Funktionsverhalten implementiert, kann sie nicht direkt aufgerufen werden. Nur überladene Signaturen sind aufrufbar.

greet('World'); // Überladene aufrufbare Signatur greet(['Xiaozhi', 'Daye']); // Überladene aufrufbare Signatur const someValue: unknown = 'Unknown';
greet(someValue); // Implementierungssignatur NICHT aufrufbar

// Einen Fehler melden. Diesem Aufruf entspricht keine Überladung.
  Überladung 1 von 2, „(Person: Zeichenfolge): Zeichenfolge“, hat den folgenden Fehler ergeben.
    Das Argument vom Typ „unbekannt“ kann keinem Parameter vom Typ „Zeichenfolge“ zugewiesen werden.
  Überladung 2 von 2, '(Personen: Zeichenfolge[]): Zeichenfolge[]', hat den folgenden Fehler ergeben.
    Das Argument vom Typ „unbekannt“ kann nicht dem Parameter vom Typ „string[]“ zugewiesen werden.

Im obigen Beispiel können Sie greet() nicht mit einem Argument vom Typ unknown (greet(someValue)) aufrufen, obwohl die Implementierungssignatur ein unknown Argument akzeptiert.

2.1 Implementierungssignaturen müssen universell sein

// Signaturfunktion überladen greet(person: string): string;
Funktion „Greet“ (Personen: Zeichenfolge []): Zeichenfolge []; 
// Diese Überladungssignatur ist mit ihrer Implementierungssignatur nicht kompatibel.

 
// Signaturfunktion implementieren greet(person: unknown): string {
  // ...
  neuen Fehler werfen (,,Begrüßung nicht möglich‘);
}

Die überladene Signaturfunktion greet(person: string[]): string[] ist als inkompatibel mit greet(person: unknown): string markiert.

string -Rückgabetyp der implementierenden Signatur ist nicht allgemein genug, um mit string[] Rückgabetyp der überladenen Signatur kompatibel zu sein.

3. Methodenüberladung

Obwohl im vorherigen Beispiel die Funktionsüberladung auf eine normale Funktion angewendet wurde. Wir können aber auch eine Methode überladen

Im Abschnitt zur Methodenüberladung sind sowohl die Überladungssignatur als auch die Implementierungssignatur Teil der Klasse.

Beispielsweise implementieren wir eine Greeter -Klasse mit einer überladenen Methode greet() .

Klasse Begrüßer {
  Nachricht: Zeichenfolge;
 
  Konstruktor(Nachricht: Zeichenfolge) {
    diese.nachricht = Nachricht;
  }
 
  // Signatur überladen greet(person: string): string;
  begrüßen(Personen: Zeichenfolge[]): Zeichenfolge[];
 
  // Signatur implementieren greet(person: unknown): unknown {
    wenn (Typ der Person === 'Zeichenfolge') {
      gib `${this.message}, ${person}!` zurück;
    } sonst wenn (Array.isArray(Person)) {
      returniere Person.Map(Name => `${this.message}, ${name}!`);
    }
    neuen Fehler werfen (,,Begrüßung nicht möglich‘);
  }

Die Greeter-Klasse enthält die überladene Methode greet(): 2 Überladungssignaturen, die beschreiben, wie die Methode aufgerufen wird, und eine Implementierungssignatur, die die korrekte Implementierung enthält

Dank Methodenüberladung können wir hi.greet() auf zwei Arten aufrufen: mit einem String oder mit einem Array von Strings als Argument.

const hi = neuer Begrüßer('Hallo');
 
hi.greet('Xiaozhi'); // 'Hallo, Xiaozhi!'
hi.greet(['Wang Daye', 'Daye']); // ['Hallo, Wang Daye!', 'Hallo, Daye!']


4. Wann sollte Funktionsüberladung verwendet werden?

Bei ordnungsgemäßer Verwendung kann die Funktionsüberladung die Benutzerfreundlichkeit von Funktionen, die auf mehrere Arten aufgerufen werden können, erheblich steigern. Dies ist besonders bei der automatischen Vervollständigung nützlich: Wir listen alle möglichen Überladungen in der automatischen Vervollständigung auf.

In manchen Fällen empfiehlt es sich jedoch, keine Funktionsüberladung zu verwenden, sondern stattdessen Funktionssignaturen zu nutzen.

Verwenden Sie beispielsweise keine Funktionsüberladung mit optionalen Parametern:

// Nicht empfohlene Funktion myFunc(): string;
Funktion myFunc(param1: Zeichenfolge): Zeichenfolge;
Funktion myFunc(Param1: Zeichenfolge, Param2: Zeichenfolge): Zeichenfolge;
Funktion meineFunktion(...args: string[]): string {
  // Implementierung...
}


Es genügt, optionale Parameter in der Funktionssignatur zu verwenden:

// Empfohlene Vorgehensweise Funktion myFunc(param1?: string, param2: string): string {
  // Implementierung...
}

5. Zusammenfassung

Durch Funktionsüberladung in TypeScript können wir Funktionen definieren, die auf mehrere Arten aufgerufen werden können.

Für die Verwendung von Funktionsüberladung ist die Definition einer Überladungssignatur erforderlich: eine Reihe von Funktionen mit Parametern und Rückgabetypen, aber ohne Hauptteil. Diese Signaturen geben an, wie die Funktion aufgerufen werden soll.

Darüber hinaus müssen Sie die korrekte Implementierung der Funktion schreiben (Implementierungssignatur): Parameter- und Rückgabetypen sowie den Funktionskörper**. Beachten Sie, dass die Implementierungssignatur nicht aufrufbar ist. **

Neben regulären Funktionen können auch Methoden innerhalb einer Klasse überladen werden.

Dies ist das Ende dieses Artikels über Funktionsüberladung in TypeScript . Weitere Informationen zur Funktionsüberladung in TypeScript finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung des Unterschieds zwischen Typ und Schnittstelle in TypeScript
  • So verwenden Sie for...in in Typescript
  • Einführung von MD5-Prüfsummen in TypeScript- und JavaScript-Projekten
  • TypeScript Core Foundation-Schnittstelle
  • TypeScript verwendet Tuple Union, um Funktionsüberladungen zu deklarieren

<<:  Detaillierte Erläuterung der grundlegenden Befehle des Docker-Ausführungsprozesses und des Images

>>:  Umfassende Erklärung zu dynamischem SQL von MyBatis

Artikel empfehlen

Implementierung zum Erstellen benutzerdefinierter Images mit Dockerfile

Inhaltsverzeichnis Vorwort Einführung in Dockerfi...

Verwenden Sie momentJs, um eine Countdown-Komponente zu erstellen (Beispielcode)

Heute möchte ich einen Countdown von Vue und Mome...

Codebeispiel für die Verwendung der MySql COALESCE-Funktion

COALESCE ist eine Funktion, die sich nacheinander...

Wie MLSQL Stack das Stream-Debugging vereinfacht

Vorwort Ein Klassenkamerad untersucht die Streami...

Verwenden einer MySQL-Datenbank im Docker, um LAN-Zugriff zu erhalten

1. Holen Sie sich das MySQL-Image Docker-Pull MyS...

Beispiele für die Verwendung der oder-Anweisung in MySQL

1. Die Verwendung der oder Syntax in MySQL und di...

So legen Sie ein Kennwort für MySQL Version 5.6 auf dem Mac fest

MySQL kann bei der Installation festgelegt werden...

MySql-Abfrageanweisung mit mehreren Bedingungen und dem Schlüsselwort „OR“

Im vorherigen Artikel wurde die MySql-Abfrageanwe...

Implementierung der mobilen Postcss-pxtorem-Anpassung

Führen Sie den Befehl aus, um das Plugin postcss-...

Absatzlayout und Zeilenumbrüche in HTML-Webseiten

Das Erscheinungsbild einer Webseite hängt maßgebl...