Есть ли способ, чтобы добавить методы на лету класса, используя машинопись?

голоса
17

Я пытаюсь создать своего рода подмешать метода, которые добавляют методы в прототипе / класс на лету, но я получаю ошибки, такие как

Свойство «greetName» не существует на значение типа «Greeter» любой

а также

Свойство «greetName» не существует на значение типа «Greeter» любой

когда я запускаю следующий код.

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

Это на самом деле компилирует уважительных JS и работает, как ожидалось. Есть ли способ сделать это с вне предупреждений компилятора / ошибок?

Задан 02/10/2012 в 22:49
источник пользователем
На других языках...                            


6 ответов

голоса
15

Это решение имеет преимущество дает вам тип проверки, когда вы динамически добавить метод:

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();
Ответил 06/06/2013 в 17:02
источник пользователем

голоса
8

Существует еще один способ сделать это.

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

Работает так же и использует функцию свойство индексатора в JavaScript и машинопись не жалуется.

Ответил 19/12/2012 в 16:06
источник пользователем

голоса
8

Они должны были бы понятие частичных классов для этой работы, которые в настоящее время не поддерживается. Я вам скажу, что я нашел, работает лучше для этих типов сценариев является использование интерфейсов вместо (я программировал в машинописном в течение 6 месяцев - я в MS, но не в команде машинописи)

Интерфейсы расширяемые постфактум просто definging методы вы добавляете к интерфейсу. В качестве примера этого, если вы устанавливаете плагин JQuery вы хотите повторно определить интерфейс IJQuery и IJQueryUtil включить плагин, дополнительные методы. С этого момента вы можете вызвать методы плагинов через $ .plugin () и машинопись будут счастливы.

Ответил 02/10/2012 в 23:22
источник пользователем

голоса
1

Подобно @Fenton примера, но без угловатых вещей:

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

interface MyClass {
    stop(): void;
}

var example = new MyClass();
example.stop(); // Allowed!!!
Ответил 26/05/2018 в 14:16
источник пользователем

голоса
0

Вот как RxJSэто делает

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

}

Это называется модуль усиливающим.

Ответил 23/10/2018 в 00:21
источник пользователем

голоса
0

После того, как реализовать динамические свойства и методы на классах, это было решение, которое я смог пойти с, чтобы предотвратить машинопись компилятора жаловаться:

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

В основном, используется метод скобки аксессоров свойств .

Ответил 26/08/2016 в 01:56
источник пользователем

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