Skip to content

Method decorator compile to ES5 get error #6865

@byeval

Description

@byeval

I'm learning TypeScript decorator and write a demo below:

class Hero {
    public name: string;
    public power: string;

    constructor(name: string, power: string) {
        this.name = name
        this.power = power
    }

    @logMethod
    showPower() {
        return `${this.name} has special power: ${this.power}`
    }
}

function logMethod(target:Function, key:string, descriptor: TypedPropertyDescriptor<any>){
  var originalMethod = descriptor.value; 

  //editing the descriptor/value parameter
  descriptor.value =  function (...args: any[]) {
      var a = args.map(a => JSON.stringify(a)).join();
      // note usage of originalMethod here
      var result = originalMethod.apply(this, args);
      var r = JSON.stringify(result);
      console.log(`Call: ${key}(${a}) => ${r}`);
      return result;
  }

  // return edited descriptor as opposed to overwriting 
  // the descriptor by returning a new descriptor
  return descriptor;
}

and compile to ES5 get code below:

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var Hero = (function () {
    function Hero(name, power) {
        this.name = name;
        this.power = power;
    }
    Hero.prototype.showPower = function () {
        return this.name + " has special power: " + this.power;
    };
    __decorate([
        logMethod
    ], Hero.prototype, "showPower");
    return Hero;
})();
function logMethod(target, key, descriptor) {
    var originalMethod = descriptor.value;
    //editing the descriptor/value parameter
    descriptor.value = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i - 0] = arguments[_i];
        }
        var a = args.map(function (a) { return JSON.stringify(a); }).join();
        // note usage of originalMethod here
        var result = originalMethod.apply(this, args);
        var r = JSON.stringify(result);
        console.log("Call: " + key + "(" + a + ") => " + r);
        return result;
    };
    // return edited descriptor as opposed to overwriting 
    // the descriptor by returning a new descriptor
    return descriptor;
}

then i run the compiled code in Chrome Canary, and got an error:

Uncaught TypeError: Cannot read property 'value' of undefined(…)

i think the problem is that the _decorate function doesn't work expectedly, it should compare with undefined instead of null.

var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;

when compare with null, method decorator cannot get the descriptor which should provided by Object.getOwnPropertyDescriptor(target, key)

Metadata

Metadata

Assignees

Labels

Needs More InfoThe issue still hasn't been fully clarified

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions