In TypeScript kann ich einen Parameter einer Funktion als Typfunktion deklarieren. Gibt es eine "typsichere" Möglichkeit, die mir fehlt? Betrachten Sie zum Beispiel Folgendes:
class Foo {
save(callback: Function) : void {
//Do the save
var result : number = 42; //We get a number from the save operation
//Can I at compile-time ensure the callback accepts a single parameter of type number somehow?
callback(result);
}
}
var foo = new Foo();
var callback = (result: string) : void => {
alert(result);
}
foo.save(callback);
Der Rückruf zum Speichern ist nicht typsicher. Ich gebe ihm eine Rückruffunktion, bei der der Parameter der Funktion eine Zeichenfolge ist, aber ich übergebe ihm eine Nummer und kompiliere ohne Fehler. Kann ich den Ergebnisparameter beim Speichern einer typsicheren Funktion festlegen?
TL; DR-Version: Gibt es ein Äquivalent zu einem .NET-Delegaten in TypeScript?
quelle
(n: number) => any
bedeutet eine Funktionssignatur?number
) akzeptiert, aber der Rückgabetyp überhaupt nicht eingeschränkt ist (kann ein beliebiger Wert sein oder sogarvoid
)n
dieser Syntax? Wären die Eingabe- und Ausgabetypen allein nicht ausreichend?Hier sind TypeScript-Entsprechungen einiger gängiger .NET-Delegaten:
quelle
Action
undFunc
-Delegierten machen den größten Teil der Notwendigkeit für bestimmte Delegatentypen überflüssig und geben C # interessanterweise den Anschein einer strukturellen Typisierung. Der Nachteil dieser Delegierten ist, dass ihre Namen keine Bedeutung haben, aber die anderen Vorteile überwiegen im Allgemeinen. In TypeScript brauchen wir diese Typen einfach nicht. Das Anti-Muster wäre alsofunction map<T, U>(xs: T[], f: Func<T, U>)
. Bevorzugenfunction map<T, U>(xs: T[], f: (x: T) => U)
Mir ist klar, dass dieser Beitrag alt ist, aber es gibt einen kompakteren Ansatz, der sich geringfügig von dem unterscheidet, was gefragt wurde, aber möglicherweise eine sehr hilfreiche Alternative darstellt. Sie können die Funktion im Wesentlichen inline deklarieren, wenn Sie die Methode aufrufen ( in diesem Fall
Foo
ssave()
). Es würde ungefähr so aussehen:Der
multipleCallback()
Ansatz ist sehr nützlich für Dinge wie Netzwerkanrufe, die erfolgreich sein oder fehlschlagen können. Unter der Annahme eines BeispielsmultipleCallbacks()
für einen Netzwerkaufruf kann beim Aufruf das Verhalten für Erfolg und Misserfolg an einer Stelle definiert werden, was für zukünftige Codeleser zu größerer Klarheit führt.Nach meiner Erfahrung bietet sich dieser Ansatz im Allgemeinen an, um prägnanter, weniger übersichtlich und insgesamt klarer zu sein.
Viel Glück euch allen!
quelle
Dies stimmt sicherlich mit dem funktionalen Programmierparadigma überein.
quelle
inputType
eher nennen alsreturnType
, oder? WoinputType
ist der Typ, vondata
dem Sie einen Parameter an diecallback
Funktion übergeben?In TS können wir Funktionen auf folgende Weise eingeben:
Funktionstypen / Signaturen
Dies wird für reale Implementierungen von Funktionen / Methoden verwendet und hat die folgende Syntax:
Beispiel:
Funktionstyp-Literale
Funktionstyp-Literale sind eine weitere Möglichkeit, den Typ einer Funktion zu deklarieren. Sie werden normalerweise in der Funktionssignatur einer Funktion höherer Ordnung angewendet. Eine Funktion höherer Ordnung ist eine Funktion, die Funktionen als Parameter akzeptiert oder eine Funktion zurückgibt. Es hat die folgende Syntax:
Beispiel:
quelle
Wenn Sie zuerst den Funktionstyp definieren, sieht er so aus
Ohne Funktionstyp unter Verwendung der einfachen Eigenschaftssyntax wäre dies:
Wenn Sie eine Schnittstellenfunktion wie generische c # -Delegierte verwenden möchten, wäre dies:
quelle
Neben dem, was andere sagten, besteht ein häufiges Problem darin, die Typen derselben Funktion zu deklarieren, die überladen sind. Ein typischer Fall ist die EventEmitter on () -Methode, die mehrere Arten von Listenern akzeptiert. Ähnliches kann passieren, wenn Sie mit Redux-Aktionen arbeiten - und dort verwenden Sie den Aktionstyp als Literal, um die Überladung zu markieren. Bei EventEmitters verwenden Sie den Literaltyp Ereignisname:
quelle