Are babel decorators the same as TypeScript's?
Yes, they are the same, in a sense that they produce the same behavior, but they have different implementations.
Both follow ECMAScript specifications and bring features early to us. You can expect what is on both of them to probably be supported by node or the browser in the future.
Code:
function f() {
console.log("f(): evaluated");
return function (target, propertyKey, descriptor) {
console.log("f(): called");
}
}
function g() {
console.log("g(): evaluated");
return function (target, propertyKey, descriptor) {
console.log("g(): called");
}
}
class C {
@f()
@g()
method() {}
}
new C().method();
TypeScript output:
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;
};
function f() {
console.log("f(): evaluated");
return function (target, propertyKey, descriptor) {
console.log("f(): called");
};
}
function g() {
console.log("g(): evaluated");
return function (target, propertyKey, descriptor) {
console.log("g(): called");
};
}
class C {
method() { }
}
__decorate([
f(),
g()
], C.prototype, "method", null);
new C().method();
Babel output:
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _dec, _dec2, _desc, _value, _class;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
function f() {
console.log("f(): evaluated");
return function (target, propertyKey, descriptor) {
console.log("f(): called");
};
}
function g() {
console.log("g(): evaluated");
return function (target, propertyKey, descriptor) {
console.log("g(): called");
};
}
var C = (_dec = f(), _dec2 = g(), (_class = function () {
function C() {
_classCallCheck(this, C);
}
_createClass(C, [{
key: "method",
value: function method() {}
}]);
return C;
}(), (_applyDecoratedDescriptor(_class.prototype, "method", [_dec, _dec2], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype)), _class));
new C().method();
Output after run:
> ts-node ts-example.ts
f(): evaluated
g(): evaluated
g(): called
f(): called
> node babel-example.js
f(): evaluated
g(): evaluated
g(): called
f(): called