Czy istnieje sposób na wykonanie przeciążenia metod w języku TypeScript?
Chcę osiągnąć coś takiego:
class TestClass {
someMethod(stringParameter: string): void {
alert("Variant #1: stringParameter = " + stringParameter);
}
someMethod(numberParameter: number, stringParameter: string): void {
alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
}
}
var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
Oto przykład tego, czego nie chcę robić (naprawdę nienawidzę tej części przeładowywania hackowania w JS):
class TestClass {
private someMethod_Overload_string(stringParameter: string): void {
// A lot of code could be here... I don't want to mix it with switch or if statement in general function
alert("Variant #1: stringParameter = " + stringParameter);
}
private someMethod_Overload_number_string(numberParameter: number, stringParameter: string): void {
alert("Variant #2: numberParameter = " + numberParameter + ", stringParameter = " + stringParameter);
}
private someMethod_Overload_string_number(stringParameter: string, numberParameter: number): void {
alert("Variant #3: stringParameter = " + stringParameter + ", numberParameter = " + numberParameter);
}
public someMethod(stringParameter: string): void;
public someMethod(numberParameter: number, stringParameter: string): void;
public someMethod(stringParameter: string, numberParameter: number): void;
public someMethod(): void {
switch (arguments.length) {
case 1:
if(typeof arguments[0] == "string") {
this.someMethod_Overload_string(arguments[0]);
return;
}
return; // Unreachable area for this case, unnecessary return statement
case 2:
if ((typeof arguments[0] == "number") &&
(typeof arguments[1] == "string")) {
this.someMethod_Overload_number_string(arguments[0], arguments[1]);
}
else if ((typeof arguments[0] == "string") &&
(typeof arguments[1] == "number")) {
this.someMethod_Overload_string_number(arguments[0], arguments[1]);
}
return; // Unreachable area for this case, unnecessary return statement
}
}
}
var testClass = new TestClass();
testClass.someMethod("string for v#1");
testClass.someMethod(12345, "string for v#2");
testClass.someMethod("string for v#3", 54321);
javascript
typescript
operator-overloading
Void-995
źródło
źródło
Odpowiedzi:
Zgodnie ze specyfikacją, TypeScript obsługuje przeciążanie metod, ale jest to dość niewygodne i zawiera wiele ręcznej pracy sprawdzającej typy parametrów. Myślę, że dzieje się tak głównie dlatego, że najbliższe przeciążenie metod w zwykłym JavaScript obejmuje również sprawdzanie, a TypeScript stara się nie modyfikować rzeczywistych treści metody, aby uniknąć niepotrzebnych kosztów wydajności w czasie wykonywania.
Jeśli dobrze to rozumiem, musisz najpierw napisać deklarację metody dla każdego z przeciążeń, a następnie jedną implementację metody, która sprawdza jej argumenty, aby zdecydować, które przeciążenie zostało wywołane. Podpis implementacji musi być zgodny ze wszystkimi przeciążeniami.
źródło
Zaktualizuj dla jasności. Przeciążanie metod w języku TypeScript jest przydatną funkcją, ponieważ umożliwia tworzenie definicji typów dla istniejących bibliotek z interfejsem API, który musi być reprezentowany.
Pisząc własny kod, możesz jednak uniknąć przeciążeń poznawczych przy użyciu parametrów opcjonalnych lub domyślnych. Jest to bardziej czytelna alternatywa dla przeciążeń metod, a także zapewnia uczciwość interfejsu API, ponieważ unikniesz tworzenia przeciążeń przy nieintuicyjnym porządkowaniu.
Ogólne prawo dotyczące przeciążeń TypeScript to:
Zwykle można osiągnąć to samo z opcjonalnymi lub domyślnymi parametrami - lub z typami unii lub z odrobiną orientacji obiektowej.
Rzeczywiste pytanie
Rzeczywiste pytanie dotyczy przeciążenia:
Teraz nawet w językach, które obsługują przeciążenia z oddzielnymi implementacjami (uwaga: przeciążenia TypeScript współużytkują jedną implementację) - programiści radzą, aby zapewnić spójność w kolejności. To sprawiłoby, że podpisy:
stringParameter
Zawsze jest wymagane, więc to idzie pierwszy. Możesz napisać to jako działające przeciążenie TypeScript:Ale zgodnie z prawem przeciążeń TypeScript możemy usunąć sygnatury przeciążenia, a wszystkie nasze testy będą nadal działać.
Rzeczywiste pytanie w rzeczywistym zamówieniu
Gdybyś był zdecydowany pozostać przy pierwotnej kolejności, przeciążenia byłyby następujące:
To dużo rozgałęziania, aby dowiedzieć się, gdzie umieścić parametry, ale naprawdę chciałeś zachować tę kolejność, jeśli czytasz tak daleko ... ale czekaj, co się stanie, jeśli zastosujemy prawo przeciążeń TypeScript?
Już wystarczająco dużo rozgałęzień
Oczywiście, biorąc pod uwagę ilość sprawdzanych typów, które musimy wykonać ... może najlepszą odpowiedzią jest po prostu wybranie dwóch metod:
źródło
number
parametr byłby drugim argumentem i byłby opcjonalny. TypeScript nie obsługuje „właściwych” przeciążeń metod - ale nawet świat C # odchodzi od przeciążeń w kierunku parametrów opcjonalnych, ponieważ w wielu przypadkach prowadzi to do bardziej czytelnego kodu.if (typeof numberParameter != 'undefined')
, prawda;)!==
aby unikać żonglerki.Chciałbym. Chcę też tej funkcji, ale TypeScript musi być kompatybilny z nietypowym JavaScriptem, który nie ma przeciążonych metod. tzn. jeśli przeciążona metoda jest wywoływana z JavaScript, może zostać wysłana tylko do jednej implementacji metody.
Jest kilka istotnych dyskusji na temat codeplex. na przykład
https://typescript.codeplex.com/workitem/617
Nadal uważam, że TypeScript powinien generować wszystkie if'ing i przełączanie, abyśmy nie musieli tego robić.
źródło
Dlaczego nie użyć opcjonalnego interfejsu zdefiniowanego przez właściwość jako argumentu funkcji.
W przypadku tego pytania użycie wbudowanego interfejsu zdefiniowanego tylko z niektórymi opcjonalnymi właściwościami mogłoby bezpośrednio utworzyć kod podobny do poniższego:
Ponieważ przeciążenie zawarte w TypeScript jest, jak wspomniano w komentarzach innych, tylko listą różnych sygnatur funkcji bez obsługi odpowiednich kodów implementacji, takich jak inne języki statyczne. Tak więc implementacja nadal musi być wykonana tylko w jednym ciele funkcji, co sprawia, że użycie przeciążania funkcji w Typescript nie jest tak wygodne, jak takie języki obsługujące rzeczywistą funkcję przeciążania.
Jednak nadal istnieje wiele nowych i wygodnych elementów zawartych w skrypcie, które nie są dostępne w starszym języku programowania, gdzie opcjonalna obsługa właściwości w anonimowym interfejsie jest takim podejściem, aby sprostać wygodnej strefie przeciążenia starszej funkcji, jak sądzę.
źródło
Jeśli istnieje wiele odmian przeciążeń metod, innym sposobem jest po prostu utworzenie klasy ze wszystkimi argumentami wewnątrz. Możesz więc przekazać tylko wybrany parametr w dowolnej kolejności.
Możesz także utworzyć konstruktor z wartościami domyślnymi i / lub przekazać kilka obowiązkowych argumentów. Następnie użyj w ten sposób:
źródło
W Javascript nie ma pojęcia przeciążenia. Typescript nie jest C # ani Java.
Ale możesz zaimplementować przeciążenie w Typescript.
Przeczytaj ten post http://www.gyanparkash.in/function-overloading-in-typescript/
źródło