Wie man aufhört, any für Callbacks zu verwenden und anfängt zu leben: Vollständige Anleitung zur Typisierung von Handler-Funktionen in TypeScript
\n\nHaben Sie jemals so etwas wie callback: any in Methodenparametern geschrieben? Wenn ja – willkommen im Club. Wenn nein – sind Sie entweder ein Genie oder fangen gerade erst mit TypeScript an. Nur ein Scherz. Aber jeder Scherz hat einen Kern Wahrheit: Laut Stack Overflow sammelt die Frage "How to define type for a function callback (as any function type, not universal any)" tausende Aufrufe. Und das nicht ohne Grund.
Das Problem ist, dass any wie ein schwarzes Loch ist: Es saugt die gesamte Typsicherheit Ihres Codes auf. Sie verlieren die Autovervollständigung, die Argumentprüfung und die Möglichkeit, Fehler bereits zur Kompilierzeit zu erkennen. Aber das Ärgste ist: any als Typ für einen Callback tötet die eigentliche Idee von TypeScript. Lassen Sie uns klären, wie man eine Callback-Funktion in einem Methodenparameter richtig typisiert, damit der Code sowohl sicher als auch elegant ist.
Warum ist Function nicht besser als any?
\n\nDer erste Impuls eines Anfängers ist, den eingebauten Typ Function zu verwenden. Schließlich ist das der Typ "irgendeine Funktion", also müsste er passen. Aber nein. Function ist ein ebenso "mülliger" Typ wie any. Er gibt keinerlei Informationen über die Signatur: wie viele Parameter die Funktion annimmt, was sie zurückgibt, welche Typen die Argumente haben. Sie sagen dem Compiler einfach: "Vertrau mir, ich weiß, was ich tue." Spoiler: Normalerweise wissen Sie es nicht.
// Schlecht: Keine Typprüfung\nfunction processData(callback: Function) {\n callback(42, "hallo"); // Fehler? Wer weiß das schon\n}\n\nMit diesem Ansatz verlieren Sie alle Vorteile der statischen Typisierung. Lassen Sie uns das korrigieren.
\n\nSchritt 1. Grundlegende Typisierung eines Callbacks: Einfach und verständlich
\n\nDer einfachste und korrekteste Weg ist, den Funktionstyp direkt im Parameter zu deklarieren. Dafür wird die Pfeilsyntax (Parameter) => Rückgabetyp verwendet. Dies ist der function type in TypeScript.
// Gut: Signatur explizit angeben\nfunction fetchData(url: string, onSuccess: (data: string) => void): void {\n // ... irgendeine Logik\n const result = "Daten vom Server";\n onSuccess(result);\n}\n\n// Verwendung – mit Autovervollständigung und Prüfung\nfetchData("/api/users", (data) => {\n console.log(data.toUpperCase()); // data ist string, alles ok\n});\n\nBeachten Sie das void im Rückgabetyp. Das bedeutet, dass wir keinen bestimmten Wert vom Callback erwarten. Wenn der Callback etwas zurückgibt, wird es ignoriert. Wenn Sie ein Ergebnis erwarten, verwenden Sie einen konkreten Typ.
Schritt 2. Callback mit mehreren Parametern
\n\nOft nehmen Callbacks mehr als ein Argument an. Zum Beispiel einen Fehlerhandler oder ein Ereignis mit Daten. Auch hier ist es ganz einfach – alle Parameter werden durch Kommas getrennt aufgelistet.
\n\n// Typ für einen Callback mit Fehler und Ergebnis\nfunction loadUser(\n userId: number,\n callback: (error: Error | null, user: { name: string; age: number } | null) => void\n): void {\n // ... Ladelogik\n const user = { name: "Anna", age: 30 };\n callback(null, user);\n}\n\n// Verwendung\nloadUser(42, (err, user) => {\n if (err) {\n console.error("Fehler:", err.message);\n return;\n }\n if (user) {\n console.log(`Hallo, ${user.name}!`);\n }\n});\n\nSehen Sie, wie TypeScript automatisch die Typen von err und user vorschlägt? Das ist Typisierung einer Callback-Funktion in Aktion. Ohne any, ohne Magie – nur strenge Prüfung.
Schritt 3. Wiederverwendbare Typen für Callbacks erstellen
\n\nWenn derselbe Callback-Typ an mehreren Stellen verwendet wird, müssen Sie ihn nicht jedes Mal duplizieren. Lagern Sie ihn in einen separaten type alias oder ein interface aus. Das verbessert die Lesbarkeit und vereinfacht die Wartung.
\n\n// Deklaration