如何在装饰器

时间:2018-03-18 21:22:48

标签: javascript typescript decorator

我正在尝试开发一个装饰器,以了解某些参数是否有效。

这是我的方法,

getUsers(offset, limit, orderBy, sort){
....
}

我需要检查orderBy是否是' createdAt'或者' updatedAt'如果没有,将发送http响应。

同样的事情,它需要是' ASC'或者' DESC'。

所以,我不知道如何使用装饰器来帮助我删除代码中的某些内容,它只是一个小块,但我觉得它更干净。目前这是我要检查的块

if (!includes(this.orderByFields, orderBy)) {
  return Utils.HttpError.badRequest(`You are allowed to order by [ ${this.orderByFields.join(', ')} ] only.`);
}

也许不可能做到这一点,谢谢提前: - )

1 个答案:

答案 0 :(得分:0)

你应该可以这样做:

type ApiFunction = (offset: number, limit: number, orderBy: string, sort: string) => any;

const orderByFields = ["createdAt", "updatedAt"];
function validateRequest() {
  return function(_target: any, _propertyName: string, descriptor: TypedPropertyDescriptor<ApiFunction>) {
    const originalMethod = descriptor.value!;
    descriptor.value = function(offset, limit, orderBy, sort) {
      if (!orderByFields.includes(orderBy)) {
        return "Bad Request";
      }
      return originalMethod.bind(this)(offset, limit, orderBy, sort);
    };
  };
}

这也确保您只能将装饰器应用于具有匹配签名的方法。

用法示例:

class Foo {
  @validateRequest()
  getUsers(offset: number, limit: number, orderBy: string, sort: string): string {
    return "Result";
  }
}

除此之外,您可能希望尝试在类型级别上强制执行orderBysort参数(如果您是此API的唯一消费者,那么您可能甚至不会需要装饰者):

function getUsers(offset: number, limit: number, orderBy: "createdAt" | "updatedAt", sort: "ASC" | "DESC") {}