如何在TypeScript中实现参数装饰器?

时间:2015-06-05 14:02:48

标签: annotations typescript decorator

我一直在尝试使用参数装饰器@logParameter

class Person {

  public name: string;
  public surname: string;

  constructor(name : string, surname : string) { 
    this.name = name;
    this.surname = surname;
  }

  public saySomethingAsync(something: string, @logParameter cb: (said : string) => void) { 
    cb(this.name + " " + this.surname + " says: " + something); 
  }
}

我的问题是,当我尝试实现装饰器时。 我对目标所做的所有更改都会被忽略

我一直在阅读一些documentation,参数装饰器无法修改目标。

  

参数装饰器函数是一个接受三个参数的函数:包含修饰参数的函数,成员的属性键(或构造函数的参数未定义)以及参数的序数索引。 忽略此装饰器的返回值

文档说我可以注释使用参数装饰器

  

注释目标和索引

然后使用方法装饰器来读取注释。它会像是这样的东西:

  @readParameterAnnotations
  public saySomethingAsync(something: string, @logParameter cb: (said : string) => void) { 
    cb(this.name + " " + this.surname + " says: " + something); 
  }

我的问题是,如果忽略对目标的所有更改,我不明白如何向目标添加注释?

function logParameter(target: any, key: string, index: number) {
  // how can I annotate the target?
}

仅使用reflect-metadata吗?

function logParameter(target: any, key: string, index: number) {
  Reflect.defineMetadata("log_parameters", index, target, key);
}

1 个答案:

答案 0 :(得分:2)

  

忽略此装饰器的返回值。

这与您的情况无关。参数装饰器的返回值被忽略,因为它们不需要能够替换任何东西(与可以替换描述符的方法和类装饰器不同)。

  

我的问题是,当我尝试实现装饰器时。 我对目标所做的所有更改都会被忽略。

目标是对象的原型。它工作正常:

class MyClass {
    myMethod(@logParam myParameter: string) {}
}

function logParam(target: any, propertyKey: string, parameterIndex: number) {
    target.test = propertyKey;
}

console.log(MyClass.prototype["test"]); // myParameter
var c = new MyClass();
console.log(c["test"]); // myParameter

只需改变这种情况就可以将数据放到你想要的位置(使用Reflect.defineMetadata可能是最好的)。