Typescript 属性 Vanilla JS 中的装饰器?

Typescript Property Decorator in Vanilla JS?

我发现一些代码在 class...

中使用装饰器作为实例变量

我试图用普通的方式复制它 Javascript,但它不起作用。

这是打字稿:

export function ObservableProperty() {
  return (obj: Observable, key: string) => {
    let storedValue = obj[key];

    Object.defineProperty(obj, key, {
      get: function () {
        return storedValue;
      },
      set: function (value) {
        if (storedValue === value) {
          return;
        }
        storedValue = value;
        this.notify({
          eventName: Observable.propertyChangeEvent,
          propertyName: key,
          object: this,
          value
        });
      },
      enumerable: true,
      configurable: true
    });
  };
}

然后,在 class:

export class MyClass extends Observable {
  @ObservableProperty() public theBoolValue: boolean;
…

我尝试了各种方法来实例化我的 JS 变量——总是出错……

喜欢:

@ObservableProperty
this.theBoolValue = false;

这可能吗?

装饰器还是一个提案,还没有正式加入JS。它们目前正在进行重大的重新设计,它们将与当前基于提案第一版的 TypeScript 实现有很大不同。您可以在此处关注提案的进展情况: https://github.com/tc39/proposal-decorators

你也可以同时使用 Babel 在 JS 中尝试装饰器,但这也是基于旧的提议(即使 legacy 选项关闭......因为装饰器实际上现在处于第三个版本)。 https://babeljs.io/docs/en/babel-plugin-proposal-decorators

因此请记住,这只是一个权宜之计,并且该代码将来可能永远无法在浏览器中本地运行 - 您需要重构它以在完成时匹配新的装饰器提案。

装饰器是 TypeScript 的东西,而不是 JavaScript 的东西 (yet)

看看 TypeScript Docs,你可以拿他们的例子(甚至你的例子),然后把它扔到他们的 Playground 上,得到一个 JavaScript 的等价物。

For example,这里是 TypeScript 示例:

function first() {
  console.log("first(): factory evaluated");
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log("first(): called");
  };
}

function second() {
  console.log("second(): factory evaluated");
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log("second(): called");
  };
}

class ExampleClass {
  @first()
  @second()
  method() {}
}

归结为 JavaScript:

"use strict";
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 __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
function first() {
    console.log("first(): factory evaluated");
    return function (target, propertyKey, descriptor) {
        console.log("first(): called");
    };
}
function second() {
    console.log("second(): factory evaluated");
    return function (target, propertyKey, descriptor) {
        console.log("second(): called");
    };
}
class ExampleClass {
    method() { }
}
__decorate([
    first(),
    second(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], ExampleClass.prototype, "method", null);