打字稿装饰器只能在同一个方法中工作

Typescript decorator only works within the same method

我正在尝试在我的一个项目中使用 Typescript 装饰器,但我遇到了一种我无法理解的奇怪行为。

它似乎只有在装饰 class 位于试图获取元数据的同一方法内时才有效:

describe('metadata tests', () => {

    it('should retrieve metadata', () => {

        class Test {
            @TestDecorator('some value')
            property: string;
        }

        const metadata = Reflect.getMetadata('test', new Test(), 'property');
        expect(metadata).toEqual('some value'); //Passes
    });

});

但是一旦我把它移到方法之外,它就不再起作用了:

describe('metadata tests', () => {

    class Test {
        @TestDecorator('some value')
        property: string;
    }

    it('should retrieve metadata', () => {
        const metadata = Reflect.getMetadata('test', new Test(), 'property');
        expect(metadata).toEqual('some value'); //Fails
    });

});

两个测试都使用这个测试装饰器:

function TestDecorator(value: any) {
    return function (target: any, propertyKey: string) {
        console.log(`I'm being decorated!`);
        Reflect.defineMetadata('test', value, target, propertyKey);
    };
}

并且两者都在打印到控制台...

此外,在两个转译后的代码中,我都可以看到 属性 被正确修饰并且完全以相同的方式修饰:

var Test = (function () {
    function Test() {
    }
    __decorate([
        TestDecorator('some value'),
        __metadata("design:type", String)
    ], Test.prototype, "property", void 0);
    return Test;
}());

这是我的tsconfig.json。我认为是正确的(es5emitDecoratorMetadataexperimentalDecorators):

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "declaration": true,
    "outDir": "dist",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": true
  },
  "exclude": [
    "node_modules",
    "dist"
  ]
}

我错过了什么?

对于有同样问题的人,我认为这不是解决方案,但就我而言,从 Webpack 切换到 Rollup.js 解决了问题...