【问题标题】:Typescript decorator confusion打字稿装饰器混淆
【发布时间】:2016-05-08 14:37:22
【问题描述】:

我一直在使用 TypeScript 装饰器,但没有让它们正常工作。我阅读了How to implement a typescript decorator?http://blog.wolksoftware.com/decorators-reflection-javascript-typescript,我从中创建了装饰器实现

function log(target: any, key: string, descriptor?: any) {

  // save a reference to the original method
  // this way we keep the values currently in the 
  // descriptor and don't overwrite what another 
  // decorator might have done to the descriptor.
  if(descriptor === undefined) {
      descriptor = Object.getOwnPropertyDescriptor(target, key);
  }
  var originalMethod = descriptor.value; 

  //editing the descriptor/value parameter
  descriptor.value =  function (...args: any[]) {
      var a = args.map(a => JSON.stringify(a)).join();
      // note usage of originalMethod here
      var result = 12;//originalMethod.apply(this, args);
      var r = JSON.stringify(result);
      console.log(`Call: ${key}(${a}) => ${r}`);
      return result;
  }

  // return edited descriptor as opposed to overwriting 
  // the descriptor by returning a new descriptor
  return descriptor;
}

class C {
    constructor(){
        console.log("built");
    }
    @log
    public foo(n: number) {
        console.log("foo called");
        return n * 2;
    }
}
//new MethodDecoratorExample().method("hi");
var c = new C();
var r = c.foo(23); //  "Call: foo(23) => 12"
console.log(r);

但是运行此代码并没有产生我所期望的结果,实际上它似乎并没有覆盖描述符。深入挖掘,我发现在生成的代码中,对__decorate 的调用只有三个参数

__decorate([
    log
], C.prototype, "foo");

这意味着在 __decorate c = 3 中没有传入描述符。因此没有返回新的描述符,并且代码流继续进行,就好像该方法没有被拦截一样。

所以我一定是错误地应用了这个装饰器,但我看不出我做错了什么。它是否可能被解释为属性描述符?我确实在某处看到了一些关于此的评论,但那是关于将 C 中的 foo 方法定义为我没有做的 lambda。

我怎样才能让它工作?

【问题讨论】:

  • TypeScript Playground 为您的代码生成 __decorate([log], C.prototype, "foo", null);。你使用什么编译器选项?
  • 我正在编译 tsc --experimentalDecorators decorator.ts 没有 .tsconfig 文件。我正在使用 1.8 测试版,但我也尝试过 1.7.5

标签: typescript decorator


【解决方案1】:

这里的问题是 TypeScript 将默认生成 ES3 代码,并且方法 decorators generated for ES3 显然与为 ES5 生成的方法有些不同。因此,除非您确实需要以 ES3 为目标,否则解决问题的简单方法是将 ES5 定位为 tsc --experimentalDecorators --target es5,或将 ES6 定位为 tsc --experimentalDecorators --target es6

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2018-02-12
    相关资源
    最近更新 更多