我正在尝试为Typescript中的REST Api接口开发装饰器.这是装饰器的实现
export function RemoteResource(params: any): Function {
console.log("RemoteResource.params: ", params);
return function (target: Function) {
//--POST
target.prototype.post = function () {
console.log("----POST");
};
//--GET
target.prototype.retrieve = function () {
console.log("----GET");
};
//--DELETE
target.prototype.remove = function () {
console.log("----DELETE");
};
//--PULL
target.prototype.update = function () {
console.log("----PULL");
};
console.log("RemoteResource.target: ", target);
return target;
}
}
现在,我可以使用装饰器@RemoteResource并将post | retrieve | remove | update方法正确添加到原始对象原型中.
@RemoteResource({
path: "/foos",
methods: [],
requireAuth: false
})
export class Foo { }
从这里开始,如果我执行
let tester = new Foo();
tester.post() //--This prints out "----POST" correctly
我已经正确打印了日志,但是我也遇到以下错误:“类型’Foo’中不存在属性’post’.”
虽然我理解为什么会有这个错误(Foo没有任何声明的post属性),但我不确定如何解决它.
理想情况下,我希望TS编译器了解装饰器扩展了原始对象,并添加了这些方法.
我该如何实现?有任何想法吗?
谢谢!
解决方法:
由于要在运行时在装饰器中动态添加这些方法,因此编译器无法知道这些方法将用于Foo实例.
您可以用不同的方式更改它,例如:
(1)使用接口和交集:
interface RemoteResource {
post(): void;
remove(): void;
update(): void;
retrieve(): void;
}
let tester = new Foo() as Foo & RemoteResource;
tester.post(); // no error
(2)接口和空方法:
export class Foo implements RemoteResource {
post: () => void;
remove: () => void;
update: () => void;
retrieve: () => void;
}
let tester = new Foo() as Foo & RemoteResource;
tester.post();
编辑
@Robba建议:
(3)忽略所有类型检查
let tester = new Foo() as any;
tester.post();
要么
let tester = new Foo();
tester["post"]();