使用方法装饰器返回undecript的Typescript方法

时间:2016-07-09 07:58:42

标签: javascript typescript1.8

如果这是一个愚蠢的问题,我道歉。我是打字稿和学习打字稿装饰的新手。我找到了一个代码:MethodDecorator来记录参数和结果。

日志装饰者

function log (target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
    let originalMethod = descriptor.value;
    descriptor.value = function (...args:any[]) {
        //before
        console.log(`${key} method called with args: ${JSON.stringify(args)}`);

        let result = originalMethod.apply(this, args);

        //after
        console.log(`${key} method return value: ${JSON.stringify(result)}`);
    }
    return descriptor;
}

我在Book类

中使用@log和setId和getId方法

book.ts

class Book{
    constructor(public id: number, public title: string, public publisher: string){}

    @log
    setId(id: number){
        this.id = id;
    }
    @log
    getId(): number{
        return this.id;
    }
}
  

当我运行此代码时,所有代码都运行正常,但getId返回undefined。

let book = new Book(1, "Learn TypeScript", "O\'Reilly Media");

let favBookId = book.getId();
console.log("Book before setId: ");
console.log(book);
console.log("Favourite book id: "+favBookId);

book.setId(5);
console.log("Book after setId: ");
console.log(book);
console.log("Favourite book id: "+favBookId);

我的tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "removeComments": false,
        "experimentalDecorators": true
    }
}

编译并运行:

tsc -p ./
node book.js

输出:

getId method called with args: []
getId method return value: 1
Book before setId:
Book {id: 1, title: 'Learn TypeScript', publisher: 'O\'Reilly Media' }
Favourite book id: undefined
setId method called with args: [5]
setId method return value: undefined
Book after setId:
Book {id: 5, title: 'Learn TypeScript', publisher: 'O\'Reilly Media' }
Favourite book id: undefined

我无法理解为什么setId正在按我的意愿工作而getId不是?

tsc -v: Version 1.8.10

2 个答案:

答案 0 :(得分:1)

我不知道为什么互联网上的所有帖子都会引用这些例子,但我对自己的方法装饰器上下文有originalMethod.apply(this, args);

的问题。

这确实不起作用(我不知道它是ts的bug还是其他的东西。)

经过试验错误,我发现以下解决方案有效,允许您在基类中拥有正确的上下文:

function myDecorator(target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {

        descriptor.value = function (...args:any[]) {
            // whatever code suits you here...
            // dont use "this", use "target"
            let result = originalMethod.apply(target, args);

        }
        return descriptor;
}

现在,您可以这样做:

export class Yeah {
    @myDecorator()
    helloWord() {
        let n = 5;
        return this.multiply(n);
    }

    multiply(a: number) {
       return a * 2;
    }

}

干杯

答案 1 :(得分:0)

OMG,我认为您的问题与我相同,但事实并非如此。

问题仅是由you return nothing重新定义功能引起的。

这是您的原始代码块:

descriptor.value = function (...args:any[]) {
        //before
        console.log(`${key} method called with args: ${JSON.stringify(args)}`);

        let result = originalMethod.apply(this, args);

        //after
        console.log(`${key} method return value: ${JSON.stringify(result)}`);
    }

现在,将其返回即可正常工作。

descriptor.value = function (...args:any[]) {
        //...
        let result = originalMethod.apply(this, args);
        //...
        return result; //ADD HERE!!!
    }