typescript - 如何在 TypeScript 中为装饰器添加可选参数?

标签 typescript decorator typescript1.8

我想创建一个可以选择接受参数的字段装饰器。
参数应包含以下任何值:nothing、 bool 值或函数。
我知道该怎么做,但我对结果不是 100% 满意:

export class TestClass{

   @Required(isRequired) 
   public testField: string;

}

export function isRequired():boolean{
   ... some validation logic, maybe depending on other fields...
   return result;
}

@Required 的实现:
export function Required(expression?: boolean|Function): Function {
    return (target: any, key: string) => {
        if (expression === null || typeof expression == 'undefined') {
            expression = true;
        }
        console.log("Required found: " + expression, ":", target, key);
        ... register the field and its validation expression for later usage
    }
}

所以这很好用,但是当我不想添加表达式(并因此使用默认的“true”表达式)时,我希望能够像这样编写它:
class TestClass{

   @Required
   public testField: string;

}

我收到一个 TypeScript 错误 (TS1240) 说:

Unable to resolve signature of property decorator when called as an expression. Supplied parameters do not match any signature of call target



所以我需要写@Required()
class TestClass{

   @Required()
   public testField: string;

}

是否可以编写一个可选参数的装饰器实现,并且当未指定该参数时,不需要添加 "()"?

最佳答案

实际上,这是可能的。

这是一个工作示例:

export type Target = {
  new (...args: any[]): any,
  name: string
};

export function Component(target: Target): void;
export function Component(name: string): (target: Target) => void;
export function Component(nameOrTarget: string | Target) {
  if (typeof nameOrTarget !== 'string') {
    console.log(nameOrTarget.name, ' is now decorated');
  } else {
    return function (target: Target) {
      const name = nameOrTarget || target.name;
      console.log(name, ' is now decorated');
    };
  }
}

@Component
export class MyDatabase { }

@Component('Hello Db')
export class MyHelloDatabase { }

最重要的部分是以下两行:
export function Component(target: Target): void;
export function Component(name: string): (target: Target) => void;

如果有人在寻找更多信息,请查看 GitHub issue .

关于typescript - 如何在 TypeScript 中为装饰器添加可选参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40234293/

相关文章:

typescript - 如何添加使用动态组件加载器创建的组件的表单值?

reactjs - Vite React TypeScript monorepo 热模块重新加载(HMR)不起作用

javascript - 模块合并 - 它是如何工作的?

javascript - Typescript/JavaScript forEach

javascript - AngularJS 1.5 配置延迟

抽象类的具体子类的 typescript 类型

html - Angular7 - Appcomponent中的访问参数

python - 方法的日志装饰器

javascript - 如何使用装饰器向类添加函数

javascript - typescript 类装饰器 : typing properties defined in decorator function