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

Grundlegende Schritte zur Sicherheitseinstellung für den CentOS7-Server

Schalten Sie den Ping-Scan aus, obwohl dies nicht...

So dockerisieren Sie eine Python-Django-Anwendung

Docker ist ein Open-Source-Projekt, das Entwickle...

MySQL View-Prinzipanalyse

Inhaltsverzeichnis Aktualisierbare Ansichten Leis...

Zusammenfassung der drei Lazy-Load-Methoden lazyLoad mit nativem JS

Inhaltsverzeichnis Vorwort Methode 1: Hoher Kontr...

Lösung für das Problem der Werteübergabe zwischen HTML-Seiten

Als ich den Aufsatz zum ersten Mal verwendete, füh...

Kopieren von Feldern zwischen verschiedenen Tabellen in MySQL

Manchmal müssen wir eine ganze Datenspalte aus ei...

Vue simuliert die Warenkorb-Abrechnungsfunktion

In diesem Artikelbeispiel wird der spezifische Co...

Versprechenskapselung wx.request-Methode

Im vorherigen Artikel wurde die Implementierungsm...

Umfassender Vergleich und Bewertung des Vue-Code-Hervorhebungs-Plugins

Inhaltsverzeichnis Umfassender Vergleich Aus der ...

Detaillierte Erklärung der Grundkonzepte von HTML

Was ist HTML? HTML ist eine Sprache zur Beschreib...

Beispiel zur Optimierung der MySQL-Einfügeleistung

MySQL-Leistungsoptimierung Die MySQL-Leistungsopt...

CSS-Schreibformat, detaillierte Erklärung der Grundstruktur einer mobilen Seite

1. CSS-Schreibformat 1. Inline-Stile Sie können C...