Как использовать декоратор метода TypeScript и сохранить нормальную область видимости this - PullRequest
0 голосов
/ 17 мая 2019

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ: Эта проблема была из-за использования решателей GraphQL при запуске моего украшенного метода.Это означало, что область действия this была undefined.Тем не менее, основы этого вопроса полезны для всех, кто сталкивается с проблемой декораторов.


Это базовый декоратор, который я хочу использовать (у меня больше кода):

const someDecorator = (argPassed: any) => {

  return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {

    const originalMethod = descriptor.value;

    // DO stuff here...
    console.log(argPassed);

    // Wrapping the original method
    descriptor.value = (...args: any[]) => {

      const result = originalMethod.apply(this, args);

      return result;
    };
  };
};

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

Это класс IЯ использую и метод, который я украшаю:

class SomeClass {

  constructor() {
  }

  @someDecorator('Passing this in...')
  public doingSomething(argPassed: string) {

    console.log(this); // Returns: { default: SomeClass { otherMethodInMyClass: [Function] } }

    //  Meaning i can't do this
    //  this.otherMethodInMyClass is not a function
    this.otherMethodInMyClass(argPassed);

  }

  private otherMethodInMyClass = (argPassed: any) => {
    // Let's go for it...
  }

}

В настоящее время декоратор передает область действия doingSomething как:

{ default: SomeClass { otherMethodInMyClass: [Function] } }

Когда не используется декоратор, я получаю:

SomeClass { doingSomething: [Function], otherMethodInMyClass: [Function] }

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

Обновление: Как справедливо упомянуто @jcalz, функция стрелки не получает свой собственный this контекст.Однако, когда я использовал функцию без стрелки на декораторе, this возвращается как undefined.

Заранее спасибо

1 Ответ

1 голос
/ 17 мая 2019

Похоже, проблема в вашем вопросе в том, что вы используете функцию стрелки в качестве метода, что не рекомендуется, поскольку функции стрелок не получают свой собственный this контекст .

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

const someDecorator = (argPassed: any) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value;
        console.log("ARGPASSED: ");
        console.log(argPassed);
        // anonymous function, not arrow
        descriptor.value = function (...args: any[]) {
            const result = originalMethod.apply(this, args);
            return result;
        };
    };
};

class SomeClass {    
    constructor() { }

    @someDecorator('Passing this in...')
    public doingSomething(argPassed: string) {   
        console.log("THIS: ")
        console.log(this); 
        this.otherMethodInMyClass(argPassed);
    }

    private otherMethodInMyClass = (argPassed: any) => { }
}

new SomeClass().doingSomething("abc");
// ARGPASSED: 
// Passing this in...
// THIS: 
// Object { otherMethodInMyClass: otherMethodInMyClass() }

Ссылка на код на игровой площадке

Хорошо выглядит для меня. Если ваша проблема не устранена, вы можете включить в свой вопрос более подробную информацию о своей конфигурации. Всегда полезно убедиться, что код в ваших вопросах представляет собой воспроизводимый пример . Удачи!

...