¿Hay una manera de hacer la sobrecarga de métodos en TypeScript?

¿Hay una manera de hacer la sobrecarga de métodos en el lenguaje TypeScript?

Quiero lograr algo como esto:

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

Aquí hay un ejemplo de lo que no quiero hacer (realmente odio esa parte de sobrecargar el hack en 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); 

5 Solutions collect form web for “¿Hay una manera de hacer la sobrecarga de métodos en TypeScript?”

De acuerdo con la especificación, TypeScript admite la sobrecarga de métodos, pero es bastante incómodo e incluye una gran cantidad de trabajo manual que verifica los tipos de parámetros. Creo que se debe principalmente a que cuanto más cerca se puede llegar a la sobrecarga de métodos en JavaScript simple, también incluye esa comprobación y TypeScript intenta no modificar los cuerpos de los métodos reales para evitar cualquier costo innecesario de rendimiento en tiempo de ejecución.

Si lo comprendo correctamente, primero debe escribir una statement de método para cada una de las sobrecargas y luego una implementación de método que verifique sus argumentos para decidir a qué sobrecarga se llamó. La firma de la implementación debe ser compatible con todas las sobrecargas.

 class TestClass { someMethod(stringParameter: string): void; someMethod(numberParameter: number, stringParameter: string): void; someMethod(stringOrNumberParameter: any, stringParameter?: string): void { if (stringOrNumberParameter && typeof stringOrNumberParameter == "number") alert("Variant #2: numberParameter = " + stringOrNumberParameter + ", stringParameter = " + stringParameter); else alert("Variant #1: stringParameter = " + stringOrNumberParameter); } } 

Actualización para mayor claridad. La sobrecarga de métodos en TypeScript es una característica útil en la medida en que le permite crear definiciones de tipo para las bibliotecas existentes con una API que necesita ser representada.

Sin embargo, al escribir su propio código, puede evitar la sobrecarga cognitiva de las sobrecargas utilizando parámetros opcionales o predeterminados. Esta es la alternativa más legible a las sobrecargas de métodos y también mantiene su API honesta, ya que evitará la creación de sobrecargas con pedidos no intuitivos.

La ley general de sobrecargas de TypeScript es:

Si puede eliminar las firmas de sobrecarga y todas sus pruebas pasan, no necesita sobrecargas de TypeScript

Por lo general, puede lograr lo mismo con parámetros opcionales o predeterminados, o con tipos de unión o con un poco de orientación a objetos.

La pregunta actual

La pregunta real pide una sobrecarga de:

 someMethod(stringParameter: string): void { someMethod(numberParameter: number, stringParameter: string): void { 

Ahora incluso en lenguajes que admiten sobrecargas con implementaciones separadas (nota: las sobrecargas de TypeScript comparten una sola implementación): los progtwigdores son consejos para brindar consistencia en el ordenamiento. Esto haría que las firmas:

 someMethod(stringParameter: string): void { someMethod(stringParameter: string, numberParameter: number): void { 

El stringParameter siempre es necesario, por lo que va primero. Podría escribir esto como una sobrecarga de TypeScript en funcionamiento:

 someMethod(stringParameter: string): void; someMethod(stringParameter: string, numberParameter: number): void; someMethod(stringParameter: string, numberParameter?: number): void { if (numberParameter != null) { // The number parameter is present... } } 

Pero siguiendo la ley de sobrecargas de TypeScript, podemos eliminar las firmas de sobrecarga y todas nuestras pruebas aún pasarán.

 someMethod(stringParameter: string, numberParameter?: number): void { if (numberParameter != null) { // The number parameter is present... } } 

La pregunta actual, en el orden real

Si estuviera decidido a persistir con el pedido original, las sobrecargas serían:

 someMethod(stringParameter: string): void; someMethod(numberParameter: number, stringParameter: string): void; someMethod(a: string | number, b?: string | number): void { let stringParameter: string; let numberParameter: number; if (typeof a === 'string') { stringParameter = a; } else { numberParameter = a; if (typeof b === 'string') { stringParameter = b; } } } 

Esa es una gran cantidad de bifurcaciones para determinar dónde colocar los parámetros, pero realmente desea conservar este orden si está leyendo hasta aquí … pero espere, ¿qué sucede si aplicamos la ley de sobrecargas de TypeScript?

 someMethod(a: string | number, b?: string | number): void { let stringParameter: string; let numberParameter: number; if (typeof a === 'string') { stringParameter = a; } else { numberParameter = a; if (typeof b === 'string') { stringParameter = b; } } } 

Ya suficiente ramificación

Por supuesto, dada la cantidad de verificación de tipos que necesitamos hacer … quizás la mejor respuesta es simplemente tener dos métodos:

 someMethod(stringParameter: string): void { this.someOtherMethod(0, stringParameter); } someOtherMethod(numberParameter: number, stringParameter: string): void { //... } 

Yo deseo. También quiero esta característica, pero TypeScript debe ser interoperable con JavaScript sin tipo que no tenga métodos sobrecargados. es decir, si se llama a su método sobrecargado desde JavaScript, solo se puede enviar a una implementación de un método.

Hay algunas discusiones relevantes en codeplex. p.ej

https://typescript.codeplex.com/workitem/617

Todavía creo que TypeScript debería generar todos los cambios y cambios para que no tengamos que hacerlo.

Javascript no tiene ningún concepto de sobrecarga. Typescript no es c # o Java.

Pero puedes implementar la sobrecarga en Typescript.

Lea esta publicación http://www.gyanparkash.in/function-overloading-in-typescript/

¿Por qué no usar la interfaz de propiedad opcional definida como el argumento de función?

Para el caso de esta pregunta, el uso de una interfaz en línea definida con algunas propiedades opcionales solo podría hacer directamente el código como el siguiente:

 class TestClass { someMethod(arg: { stringParameter: string, numberParameter?: number }): void { let numberParameterMsg = "Variant #1:"; if (arg.numberParameter) { numberParameterMsg = `Variant #2: numberParameter = ${arg.numberParameter},`; } alert(`${numberParameterMsg} stringParameter = ${arg.stringParameter}`); } } var testClass = new TestClass(); testClass.someMethod({ stringParameter: "string for v#1" }); testClass.someMethod({ numberParameter: 12345, stringParameter: "string for v#2" }); 

Debido a que la sobrecarga provista en TypeScript es, como se menciona en los comentarios de otros, solo una lista de firmas de diferentes funciones sin admitir los códigos de implementación correspondientes como otros lenguajes estáticos. Por lo tanto, la implementación aún debe realizarse en un solo cuerpo de función, lo que hace que el uso de la sobrecarga de funciones en Typescript no sea tan cómodo como los lenguajes que admiten la función de sobrecarga real.

Sin embargo, todavía hay muchas cosas nuevas y convenientes en escritura de tipos que no están disponibles en el lenguaje de progtwigción legado, donde creo que el soporte de propiedad opcional en una interfaz anónima es un método para satisfacer la zona cómoda de la sobrecarga de la función legada.

Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.