如何使用TypeScript方法修饰符并保留常规的“ this”范围

时间:2019-05-17 15:28:16

标签: typescript ts-node typescript-decorator

请注意:此问题是由于在运行我的修饰方法时使用了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范围。

这是我正在使用的类以及我正在装饰的方法:

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

预先感谢

2 个答案:

答案 0 :(得分:1)

您问题中的问题似乎是您使用箭头函数作为方法,自arrow functions don't get their own this context开始不建议这样做。

您继续说,更改此设置不能解决您的问题,但我无法重现该问题:

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() }

Link to code in Playground

对我很好。如果问题仍然存在,则可能要在问题中包括有关配置的更多详细信息。确保您的问题中的代码构成reproducible example总是有帮助的。祝你好运!

答案 1 :(得分:0)

在使用类的方法作为GraphQL解析器时,我遇到了同样的问题,而解决该问题的唯一方法是将类用作单例,然后从单例调用其他私有方法 this