Typescript Decorator Add Initializer is not triggered when using Babel

46 views Asked by At

Today i decided to try out a Bundler, and wanted to use Babel,

Before i switched to Babel my decorators worked fine, however now i noticed that the class property addInitializers arent working anymore.

For Context, im currently building my own DI Container in Typescript.

Decorator code:

export function Inject(name: string) {
    console.log("Inject");
    let stop = true;
    return function (target: any, context: ClassFieldDecoratorContext) {

        console.log("Inject 2");
        context.addInitializer(function () {
            if (this["_dependencyBindDataList"] == undefined) {
                this["_dependencyBindDataList"] = [];
            }
            console.log("Inject 3");
            (this["_dependencyBindDataList"] as PropertyBindData[]).push({
                property: context.name as string,
                target: name,
                type: DependencyType.SINGULAR
            });
        })
    }
}

the third console log never gets triggered.

I used Two test classes for this:

class Test {
    @Inject("folderOrganisationPopulator")
    public test;

}

class Test2 {
    @Inject("test2")
    public test2;
}

and they get instanciated in their own component methods:

@Component("test")
public test(){
    return new Test();
}

@Component("test2")
public test2(){
    return new Test2();
}

They worked before i switched to Babel, so i think babel is probably configured wrong:

my babel config is:

{
  "presets": [
    [
      "@babel/env",
      {
        "modules": false,
        "targets": {
          "node": "18"
        }
      }
    ],
    "@babel/typescript"
  ],
  "sourceMaps": true,
  "plugins": ["add-import-extension",["@babel/plugin-proposal-decorators", { "version": "2023-05" }]]
}
1

There are 1 answers

1
0x5afe On BEST ANSWER

The problem is with typescript implementation for decorators. Try to return your initializer function instead of adding it to the context.

Your Decorator would look like this:

export function Inject(name: string) {
console.log("Inject");
let stop = true;
return function (target: any, context: ClassFieldDecoratorContext) {

    console.log("Inject 2");
    return function (this: any) {
        if (this["_dependencyBindDataList"] == undefined) {
            this["_dependencyBindDataList"] = [];
        }
        console.log("Inject 3");
        (this["_dependencyBindDataList"] as PropertyBindData[]).push({
            property: context.name as string,
            target: name,
            type: DependencyType.SINGULAR
        });
    }
}

Also fix the "this" reference