【发布时间】:2020-04-27 16:56:06
【问题描述】:
我正在尝试实现一个通用的方法装饰器,它可以与原型方法和实例方法一起使用。
基于:Typescript decorators not working with arrow functions
从下面的代码可以看出,instanceMethod() 正在返回一个 Promise。
有没有办法可以返回正确的值?
装饰器代码:
export function trace(verbose: boolean = false) {
return (target: any, prop: string, descriptor?: TypedPropertyDescriptor<any>): any => {
let fn
let patchedFn
if (descriptor) {
fn = descriptor.value
}
return {
configurable: true,
enumerable: false,
get() {
if (!patchedFn) {
patchedFn = async (...args) => {
const ret = fn.call(this, ...args)
console.log(`typeof ret: ${typeof ret}`)
console.log(`return value: ${ret}`)
return ret
}
}
console.log(`get() patchedFn: ${patchedFn}`)
return patchedFn
},
set(newFn) {
console.log(`set() newFn: ${newFn}`)
patchedFn = undefined
fn = newFn
},
}
}
}
测试类&测试代码:
class Greeter {
@trace()
public instanceMethod(s: string): string {
return s
}
@trace()
public async instanceAsyncMethod(s: string): Promise<string> {
return s
}
@trace()
public instanceArrowMethod = (s: string): string => {
return s
}
}
async function test() {
const greeter = new Greeter()
const result1 = greeter.instanceMethod('1')
console.log(`* instanceMethod: ${result1}`) // should return '1', instead returns a Promise
const result2 = await greeter.instanceAsyncMethod('2')
console.log(`* instanceAsyncMethod: ${result2}`)
const result3 = await greeter.instanceArrowMethod('3')
console.log(`* instanceArrowMethod: ${result3}`)
}
test()
输出:
set() newFn: (s) => {
return s;
}
get() patchedFn: (...args) => __awaiter(this, void 0, void 0, function* () {
console.log(`typeof fn: ${typeof fn}`);
const ret = fn.call(this, ...args);
console.log(`typeof ret: ${typeof ret}`);
console.log(`return value: ${ret}`);
return ret;
})
typeof ret: string
return value: 1
* instanceMethod: [object Promise] <<<<<<<<<< The instance method is returning a Promise
get() patchedFn: (...args) => __awaiter(this, void 0, void 0, function* () {
console.log(`typeof fn: ${typeof fn}`);
const ret = fn.call(this, ...args);
console.log(`typeof ret: ${typeof ret}`);
console.log(`return value: ${ret}`);
return ret;
})
typeof ret: object
return value: [object Promise]
* instanceAsyncMethod: 2
get() patchedFn: (...args) => __awaiter(this, void 0, void 0, function* () {
console.log(`typeof fn: ${typeof fn}`);
const ret = fn.call(this, ...args);
console.log(`typeof ret: ${typeof ret}`);
console.log(`return value: ${ret}`);
return ret;
})
typeof ret: string
return value: 3
* instanceArrowMethod: 3
【问题讨论】:
标签: javascript node.js typescript typescript-typings