我想创建一个可选择接受参数的字段装饰器。 参数应包含以下任何值:nothing,boolean或function。 我知道怎么做,但我对结果并不百分之百:
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)说:
在调用时无法解析属性修饰符的签名 表达。提供的参数与任何呼叫签名都不匹配 目标
所以我需要写@Required()
class TestClass{
@Required()
public testField: string;
}
是否可以编写一个可选择带参数的装饰器实现,当没有指定该参数时,不需要添加"()" ?
答案 0 :(得分:3)
实际上,有可能。
这是一个有效的示例:
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。
答案 1 :(得分:2)
你可以做的是将两者分成两个不同的功能:
function Required(target: any, key: string, expression?: boolean | Function) {
if (expression === null || typeof expression == 'undefined') {
expression = true;
}
console.log("Required found: " + expression, ":", target, key);
}
function RequiredWith(expression: boolean | Function): Function {
return (target: any, key: string) => {
return Required(target, key, expression);
}
}
然后你可以:
class TestClass {
@Required
public testField: string;
}
或者:
class TestClass2 {
@RequiredWith(true)
public testField: string;
}