2013-02-11 21 views
35

Dlaczego funkcja Types nie ostrzega mnie, że funkcja, którą definiuję, nie jest zgodna z deklaracją interfejsu, ale ostrzega mnie, jeśli spróbuję wywołać funkcję.Interfejs funkcji maszynopisu

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. 

Odpowiedz

53

interfejs zapewnia, że ​​wszystkie osoby dzwoniące z funkcji, które implementują interfejs dostarczenia wymaganych argumentów - data i toUpper.

Ponieważ TypeScript rozumie, że JavaScript nie ma nic przeciwko przekazywaniu argumentów, które nie są używane, sprytnie pozwala na to w implementacjach.

Dlaczego to jest w porządku? Ponieważ oznacza to, że możesz zastąpić dowolną implementację interfejsu bez wpływu na kod wywołujący.

Przykład: Możesz zastąpić implementację IFormatter, a kod działa.

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); 

maszynopis Jeśli nie to zrobić, Twój upperCaseFormatter musiałby mieć parametr zwany toUpper, który nie był używany w dowolnym miejscu funkcji - co sprawia, że ​​kod mniej czytelny.

+0

Ale wtedy użycie 'upperCaseFormatter' ma nadmiarową wartość boolowską:' upperCaseFormatter ("test", true); // wyłączenie "true" spowoduje wyświetlenie ostrzeżenia kompilatora ". Zamiast tego interfejs jest nieprawidłowy i powinien wyglądać następująco: 'interface IFormatter {(data: string, toUpper?: Bool): string; } 'Ale to oznacza, że ​​możesz wywołać' variableCaseFormatter' za pomocą 'variableCaseFormatter ('test');' bez określania 'toUpper' pomimo tego, że znajduje się w sygnaturze funkcji. Zobacz moje pytanie tutaj dla prostszego przykładu mojego obecnego zamieszania: http://stackoverflow.com/questions/23305020 – AJP

+5

@AJP jeśli piszesz czysty kod, nigdy nie napiszesz zmiennego formatera. Napiszesz jedną klasę dla górnej, a drugą dla niższej i unikniesz nieprzyjemnego argumentu boolowskiego. – Fenton

+0

@AJP W przypadku, gdy wywołasz 'upperCaseFormatter' bezpośrednio interfejs jest nieistotny. –

Powiązane problemy