2013-02-11 7 views
35

Warum warnt Typescript mich nicht, dass die Funktion, die ich definiere, nicht mit der Interface-Deklaration übereinstimmt, aber es warnt mich, wenn ich versuche, die Funktion aufzurufen.Typescript Function Interface

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. 

Antwort

53

Die Schnittstelle stellt sicher, dass alle Anrufer von Funktionen, die die Schnittstelle liefern die erforderlichen Argumente implementieren - data und toUpper.

Da TypeScript versteht, dass es JavaScript nichts ausmacht, wenn Sie nicht verwendete Argumente übergeben, wird dies in Implementierungen geschickt ermöglicht.

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

Beispiel: Sie können entweder IFormatter Implementierung ersetzen und der Code funktioniert.

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

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

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

    return data.toLowerCase(); 
} 

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

formatter("test", true); 

Wenn Typoskript dies nicht tun, Ihre upperCaseFormatter müßten einen Parameter aufgerufen haben müssen toUpper, die nicht überall in der Funktion verwendet wurde - was der Code weniger lesbar macht.

+0

Aber dann hat 'upperCaseFormatter' einen redundanten booleschen Wert:' upperCaseFormatter ("test", true); // Wenn "true" ausgeschlossen wird, wird eine Compiler-Warnung angezeigt. Also ist die Schnittstelle falsch und sollte sein: 'Interface IFormatter {(Daten: String, toUpper?: Bool): String; } 'Das heißt aber, dass Sie' variableCaseFormatter' mit nur 'variableCaseFormatter ('test');' ohne Angabe von 'toUpper' aufrufen können, obwohl es sich in der Funktionssignatur befindet. Sehen Sie meine Frage hier für ein einfacheres Beispiel meiner gegenwärtigen Verwirrung: http://StackOverflow.com/Questions/23305020 – AJP

+5

@AJP wenn Sie sauberen Code schreiben würden, würden Sie nie einen variablen Fall Formatierer schreiben. Sie würden eine Klasse für die obere und eine für die untere schreiben und das widerliche boolesche Argument ganz vermeiden. – Fenton

+0

@AJP Wenn Sie 'upperCaseFormatter' direkt aufrufen, ist die Schnittstelle irrelevant. –

Verwandte Themen