我想创建一个现场装饰任选可以带参数。参数应该包含以下任何值:没有什么,一个布尔或函数。我知道如何做到这一点,但我不是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
}
}
所以这个工作得很好,但是当我不想添加表达式(因此使用默认的“真”表达)我希望能够把它写这样的:
class TestClass{
@Required
public testField: string;
}
我得到一个错误的打字稿(TS1240)说:
当无法称为一个表达式来解决财产装饰的签名。提供的参数不匹配,通话对象的任何签名
所以,我需要写@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。
不,你可能无法做到这一点。 其原因是,装饰有特定的签名(其取决于该装饰的类型)。 如果您使用的装饰功能,那么你不需要括号,但如果使用a decorator factory(就像你在你的例子做),那么你必须用括号调用它。
你可以做的是分离两成两个不同的功能:
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;
}
(Qazxswpoi)