Reflect.decorate VS 在 TypeScript 中手动装饰

Reflect.decorate VS decorating manually in TypeScript

我有两个装饰器如下:

import "reflect-metadata";

const enum MetadataTypes {
  Type = "design:type",
  Paramtypes = "design:paramtypes",
  ReturnType = "design:returntype"
}

function Decorator1(target: any, key: string): void {
  console.log(`Applied Decorator1 to ${key} on ${target.constructor.name}`);
  const type = Reflect.getMetadata(MetadataTypes.Type, target, key);
  console.log(type.name);
}

function Decorator2(target: any, key: string): void {
  console.log(`Applied Decorator2 to ${key} on ${target.name}`);
  const type = Reflect.getMetadata(MetadataTypes.Type, target, key);
  console.log(type);
}

一个是手动申请的:

export class MyClass {
  @Decorator1
  private foo: string;
}

另一个使用Reflect.decorate:

Reflect.decorate([Decorator2], MyClass, "foo");

为什么使用 Reflect 应用的装饰器无法检索数据类型?

日志输出为:

Applied Decorator1 to foo on MyClass
String

Applied Decorator2 to foo on MyClass
undefined

要实现与 Reflect.decorate 类似的行为,您必须传递 class 的原型。

import "reflect-metadata";

const enum MetadataTypes {
  Type = "design:type",
  Paramtypes = "design:paramtypes",
  ReturnType = "design:returntype"
}

function Decorator1(target: any, key: string): void {
  console.log(`Applied Decorator1 to ${key} on ${target.constructor.name}`);
  const type = Reflect.getMetadata(MetadataTypes.Type, target, key);
  console.log(type.name);
}

export class MyClass {
  private foo: string;
}

Reflect.decorate([Decorator1], MyClass.prototype, "foo");

// Output:
// Applied Decorator1 to foo on MyClass
// undefined

问题是使用Reflect.decorate时没有生成元数据。

使用装饰器语法使编译器保存可以通过 Reflect.getMetadata.

访问的元数据(当 emitDecoratorMetadata 启用配置选项时)

您可以在这里阅读:https://github.com/Microsoft/TypeScript/issues/2577