TypeScript Function Overloading: Keine „Magie“, sondern ein Werkzeug für intelligenten Code
\n\nWenn Sie jemals in JavaScript eine Funktion geschrieben haben, die „mal einen String, mal eine Zahl, mal ein Array“ akzeptiert, kennen Sie das unangenehme Gefühl: Im Inneren der Funktion herrscht ein Chaos aus if-Abfragen, und von außen ist völlig unklar, was der Aufrufer eigentlich erwartet. TypeScript löst dieses Problem elegant, aber nicht immer offensichtlich. Funktionsüberladung (Function Overloading) bedeutet nicht, mehrere Funktionen mit demselben Namen zu erstellen (wie in Java oder C++). Es geht darum, mehrere Signaturen für eine einzige Implementierung zu deklarieren.
Im Jahr 2025, in dem TypeScript zum De-facto-Standard für ernsthafte Frontend- und Backend-Projekte geworden ist, ist die Fähigkeit, Überladungen geschickt einzusetzen, keine „Spielerei“ mehr, sondern eine Fähigkeit, die Ihren Code lesbar, typsicher und teamfreundlich macht. Lassen Sie uns genau anschauen, wie das funktioniert, woran Anfänger scheitern und welche Muster Sie unbedingt übernehmen sollten.
\n\nWas ist Funktionsüberladung eigentlich?
\n\nStellen Sie sich vor, Sie schreiben eine Funktion formatDate. Sie soll in der Lage sein:
- \n
- Ein
Date-Objekt zu akzeptieren und einen String zurückzugeben. \n - Einen String im ISO-Format zu akzeptieren und einen String zurückzugeben. \n
- Eine Zahl (Timestamp) zu akzeptieren und einen String zurückzugeben. \n
Wenn Sie einfach function formatDate(input: Date | string | number): string schreiben, kann TypeScript nicht erkennen, welchen Typ Sie in einem bestimmten Aufruf übergeben. Die IDE zeigt den allgemeinen Typ an, und Sie verlieren die Autovervollständigung. Die Überladung löst das:
// Überladungssignaturen (overload signatures)\nfunction formatDate(input: Date): string;\nfunction formatDate(input: string): string;\nfunction formatDate(input: number): string;\n\n// Implementierung (implementation signature)\nfunction formatDate(input: Date | string | number): string {\n if (input instanceof Date) {\n return input.toISOString();\n } else if (typeof input === 'string') {\n return new Date(input).toISOString();\n } else {\n return new Date(input).toISOString();\n }\n}\n\nWenn Sie jetzt formatDate(new Date()) aufrufen, weiß TypeScript, dass ein string zurückgegeben wird, und schlägt die richtigen Typen vor. Keine Magie – nur strenge Typisierung.
Regel Nr. 1: Überladungssignaturen sind keine Implementierungen
\n\nDer häufigste Fehler von Anfängern ist der Versuch, den Funktionskörper in jeder Signatur zu schreiben. Machen Sie das nicht:
\n\n// ❌ Fehler: Doppelte Implementierung\nfunction foo(x: number): number {\n return x * 2;\n}\nfunction foo(x: string): string {\n return x.toUpperCase();\n}\n\nTypeScript unterstützt keine mehrfachen Implementierungen mit demselben Namen. Immer eine Implementierung, mehrere Deklarationen.
\n\nRegel Nr. 2: Die Reihenfolge der Signaturen ist entscheidend
\n\nTypeScript prüft die Signaturen von oben nach unten. Die erste passende Signatur bestimmt den Rückgabetyp. Daher:
\n- \n
- Setzen Sie spezifischere Typen weiter oben (z. B.
stringvorany). \n - Vermeiden Sie sich überschneidende Signaturen, die den Compiler verwirren könnten. \n
// Gut: Zuerst der spezifische Fall\nfunction createButton(label: string, disabled?: boolean): HTMLButtonElement;\nfunction createButton(options: { label: string; disabled?: boolean }): HTMLButtonElement;\nfunction createButton(labelOrOptions: string | { label: string; disabled?: boolean }, disabled?: boolean): HTMLButtonElement {\n // Implementierung\n}\n\nRegel Nr. 3: Verwenden Sie Union Types bei mehr als 3 Signaturen
\n\nÜberladung ist ein mächtiges Werkzeug, aber übertreiben Sie es nicht. Wenn Sie 5+ Signaturen haben, wird der Code unlesbar. Im Jahr 2025 gilt als gute Praxis:
\n- \n
- Bis zu 3 Signaturen – verwenden Sie Überladung. \n
- Mehr als 3 – denken Sie über einen
Union Typeoder eine