Добавление метода к методу класса в машинописи (javascript) - PullRequest
0 голосов
/ 05 октября 2018

Я бы хотел добавить метод к методу:

class MyClass {
    public foo(text: string): string {
        return text + ' FOO!'
    }

    // Some magical code which adds the method `bar` to `foo`.
}

const obj = new MyClass();
console.log(obj.foo('thing'));
console.log(obj.foo.bar('other thing'));

Возможно ли это?Я нашел аналогичный случай для функций:

function Sum(x: number) { /*...*/ }
namespace Sum {
    export function empty() { /*...*/ }
}

Есть ли способ сделать то же самое с методами класса?

Я хотел бы иметькод в классе, а не monkeypatched после создания объекта.

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

Вы можете получить доступ к функции в прототипе классов и делать с ней все что угодно.Я не думаю, что это особенно красиво, но вы можете сделать что-то вроде этого:

class MyClass {
  constructor(myName) {
    this.myName = myName
    this.constructor.prototype.foo.bar = (function(a) {
      console.log(this.myName, "calling foo.bar with:", a)
    }).bind(this)
  }
  foo(text) {
    return text + ' FOO!'
  }

}

const obj = new MyClass("Mark");
obj.foo.bar('thing')
console.log(obj.foo('test'))
0 голосов
/ 05 октября 2018

ОБНОВЛЕНИЕ: Эту проблему можно решить чисто, используя типы пересечений :

class MyClass {

    constructor() {
        this.foo = function () {
            return "this is a"
        };

        this.foo.bar = function() {
            return "this is b"
        };
    }

    public foo: Function & { bar?: () => string };
}

const obj = new MyClass();

console.log(obj.foo());
console.log(obj.foo.bar());

Протестируйте его в Typescript Playgroung

Это возможно, потому что, используя знак & в определении типа метода класса, мы суетимся вместе как Function тип, так и простой тип объекта, который имеет 1 свойство bar это сама другая функция.Однако это свойство должно быть объявлено необязательным во втором типе, потому что Typescript будет жаловаться, что в первом присваивании внутри конструктора класса оно не удовлетворяет этому дополнительному типу.Но в действительности следующее выражение в конструкторе завершает его, присваивая свойство bar foo.

--- СТАРЫЙ ответ следует, не используйте это, оно не делает точночто хотел ОП

Вместо метода определите метод доступа к получателю для члена класса 'foo', который возвращает объект с функцией 'bar'

    class MyClass {
        get foo(): {bar: (text: string) => string} {

            // run any code here that needs to be run before bar()

            return {
                bar: (text: string) => {
                    return text + ' FOO!';
                }
            }
        }
    }

    const obj = new MyClass();
    console.log(obj.foo.bar('thing'));
0 голосов
/ 05 октября 2018

Не совсем то, что вы просите, но конечный результат работает:

class MyClass {
  public foo: MyChildClass = new MyChildClass();
}

class MyChildClass {
  public bar(text: string): string{
    return text;
  }
}

const obj = new MyClass();
console.log(obj.foo.bar('thing'));

РЕДАКТИРОВАТЬ Я прочитал ваш ответ на мой комментарий.Я думаю, что более простой способ достижения вашей цели - использовать параметры по умолчанию, такие как:

function foo(text: string, snapshot = false): string{
  if(snapshot){
    return 'snapshot';
  }
  return text;
}

console.debug(foo('test'));
console.debug(foo('test', true));

Теперь у вашего решения есть преимущество, которое вы можете увидеть на сайте вызовов, что вы явно запрашиваете обход или снимокиз-за дополнительных имен функций.Вы можете получить аналогичный результат в машинописном тексте, заменив аргументы foo интерфейсом с необязательными свойствами.На других языках мы бы назвали эту технику именованными параметрами:

interface iFooArgs{
  text: string;
  bypass?: boolean;
  snapshot?: boolean;
}

function foo(args: iFooArgs): string {
  if(args.bypass){
    return 'bypass';
  }
  if(args.snapshot){
    return 'snapshot';
  }
  return args.text;
}

console.debug(foo({text: 'test'}));
console.debug(foo({text: 'bypass?', bypass: true}));
console.debug(foo({text: 'snapshot?', snapshot: true}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...