Typescript-Funktionsschnittstelle

72

Warum warnt mich Typescript nicht, dass die von mir definierte Funktion nicht mit der Schnittstellendeklaration übereinstimmt, aber es warnt mich, wenn ich versuche, die Funktion aufzurufen.

interface IFormatter {
    (data: string, toUpper : boolean): string;
};

//Compiler does not flag error here.
var upperCaseFormatter: IFormatter = function (data: string) {
    return data.toUpperCase();
}  

upperCaseFormatter("test"); //but does flag an error here.
MBeckius
quelle

Antworten:

96

Die Schnittstelle stellt sicher, dass alle Aufrufer von Funktionen, die die Schnittstelle implementieren, die erforderlichen Argumente liefern - dataund toUpper.

Da TypeScript versteht, dass JavaScript nichts dagegen hat, wenn Sie Argumente übergeben, die nicht verwendet werden, lässt dies dies in Implementierungen geschickt zu.

Warum ist das in Ordnung? Weil dies bedeutet, dass Sie jede Implementierung der Schnittstelle ersetzen können, ohne den aufrufenden Code zu beeinflussen.

Beispiel: Sie können jede IFormatterImplementierung ersetzen und der Code funktioniert.

interface IFormatter {
    (data: string, toUpper: boolean): string;
};

var upperCaseFormatter: IFormatter = function (data: string) {
    return data.toUpperCase();
}

var variableCaseFormatter: IFormatter = function (data: string, toUpper: boolean) {
    if (toUpper) {
        return data.toUpperCase();
    }

    return data.toLowerCase();
}

// Switch between these at will
//var formatter = upperCaseFormatter;
var formatter = variableCaseFormatter;

formatter("test", true);

Wenn TypeScript dies nicht tun upperCaseFormatterwürde , müsste ein Parameter namens aufgerufen werden toUpper, der an keiner Stelle in der Funktion verwendet wird - wodurch der Code weniger lesbar wird.

Fenton
quelle
1
Aber dann hat using upperCaseFormattereinen redundanten booleschen Wert : upperCaseFormatter("test", true); // excluding the 'true' will result in a compiler warning. Stattdessen ist die Schnittstelle falsch und sollte sein: interface IFormatter { (data: string, toUpper? : bool): string; } Dies bedeutet dann aber, dass Sie variableCaseFormattermit nur variableCaseFormatter('test'); ohne Angabe aufrufen können, toUpperobwohl sie in der Funktionssignatur enthalten ist. Siehe meine Frage hier für ein einfacheres Beispiel meiner aktuellen Verwirrung: stackoverflow.com/questions/23305020
AJP
7
@AJP Wenn Sie sauberen Code schreiben würden, würden Sie niemals einen variablen Fallformatierer schreiben. Sie würden eine Klasse für die obere und eine für die untere Klasse schreiben und das böse boolesche Argument insgesamt vermeiden.
Fenton
@AJP Für den Fall, dass Sie upperCaseFormatterdirekt aufrufen, ist die Schnittstelle irrelevant.
Angry Dan
Gibt es eine bessere Syntax für die Bereitstellung einer solchen Funktionsschnittstelle für eine Objektmethode? z.B. {<IFormatter> myMethod () {return;}}
Artur Tagisow