¿Hay una manera de añadir métodos sobre la marcha para una clase usando mecanografiado?

votos
17

Estoy tratando de crear algún tipo de método de mixin que añaden métodos al prototipo / clase sobre la marcha pero me da errores como

La propiedad 'greetName' no existe sobre el valor del tipo 'Greeter' cualquier

y

La propiedad 'greetName' no existe sobre el valor del tipo 'Greeter' cualquier

cuando corro el siguiente código.

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return Hello,  + this.greeting;
    }
}

Greeter.prototype.greetName = function(name){
        return this.greet() + ' ' + name;
}

var greeter = new Greeter('Mr');

window.alert(greeter.greetName('Name'));

En realidad, compila y se ejecuta a js válidos como se esperaba. ¿Hay una manera de hacer esto con las advertencias del compilador / fuera errores?

Publicado el 02/10/2012 a las 22:49
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
15

Esta solución tiene la ventaja de dar a escribir cheques cuando agrega dinámicamente un método:

class MyClass {
    start() {

    }
}
var example = new MyClass();
// example.stop(); not allowed


interface MyClass {
  stop(): void;
}

MyClass.prototype['stop'] = function () {
    alert('Stop');
}
var stage2 = example;
stage2.stop();
Respondida el 06/06/2013 a las 17:02
fuente por usuario

votos
8

Hay otra manera de hacer esto.

Greeter["SomeProperty"] = function() {
     return "somevalue";
};

Funciona de la misma y utiliza la función indexador propiedad en javascript y mecanografiado no se queja.

Respondida el 19/12/2012 a las 16:06
fuente por usuario

votos
8

Que necesitarían un concepto de clases parciales para que esto funcione, que no se admite actualmente. Voy a decir que lo que he encontrado funciona mejor para este tipo de escenarios es el uso de interfaces de lugar (he estado programando a máquina de escribir durante unos 6 meses - Estoy en la EM, pero no en el equipo de mecanografiado)

Las interfaces son extensibles después del hecho simplemente definging los métodos que está añadiendo a la interfaz. Como ejemplo de esto, si se instala un plugin jQuery que querrá volver a definir la interfaz IJQuery y IJQueryUtil para incluir los plugins de métodos adicionales. A partir de ese punto en adelante se puede invocar los métodos a través de plugins $ .plugin () y mecanografiado será feliz.

Respondida el 02/10/2012 a las 23:22
fuente por usuario

votos
1

Al igual que en @Fenton ejemplo, pero sin el material retorcido:

class MyClass {
    start() {
    }
}
MyClass.prototype['stop'] = function () {
    alert('Stop');
}

interface MyClass {
    stop(): void;
}

var example = new MyClass();
example.stop(); // Allowed!!!
Respondida el 26/05/2018 a las 11:16
fuente por usuario

votos
0

Así es como RxJSlo hace

import {Observable} from "./observable"; // which is Greeter in your case 


declare module "./observable" {
    interface Observable<T> {
        map<U>(f: (x: T) => U): Observable<U>;
    }
}

Observable.prototype.map = function (f) {

}

Esto se llama módulo de aumento.

Respondida el 23/10/2018 a las 00:21
fuente por usuario

votos
0

Después de tener que aplicar métodos y propiedades dinámicas de las clases, esta fue la solución que yo era capaz de ir a imprenta para evitar que el compilador de quejarse:

...
window.alert(greeter['greetName']('Name'));

Básicamente, utilice el método de soporte de acceso de propiedad .

Respondida el 25/08/2016 a las 22:56
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more