InversifyJS icon indicating copy to clipboard operation
InversifyJS copied to clipboard

Support typescript stage 3 decorator

Open yeongjet opened this issue 1 year ago • 1 comments

I'm going to use stage 3 decorator in my typescript project with inversify, but can't not use stage 2 and stage 3 decorator at the same time.Any plan to support stage 3 decorator?

yeongjet avatar May 05 '23 08:05 yeongjet

@yeongjet is that even possible? Ecmascript decorators are only for classes, methods and properties, and they are not compatible with emitting class metadata. If they could coexist with legacy decorators, there is room to update injectable to be an ecmascript decorator. Otherwise it's not possible at all since inject cannot be expressed since it's a parameter decorator.

Having a closer look to the proposal, https://github.com/tc39/proposal-decorators#how-should-i-use-decorators-in-transpilers-today and https://github.com/tc39/proposal-decorators#comparison-with-typescript-experimental-decorators really got my attention. Long story short: it's too early to consider transitioning to Ecmascript decorators imo. If https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#parameter-decorators-and-annotations is finally proposed, it will be a different story.

notaphplover avatar May 05 '23 23:05 notaphplover

Any update on this?

pabloimrik17 avatar Apr 01 '24 16:04 pabloimrik17

This is slowly getting serious as more and more packages start ditching legacy decorators and start using @babel/plugin-proposal-decorators with 2023-05 (MobX in my case).

murat-mehmet avatar Apr 18 '24 14:04 murat-mehmet

as @notaphplover has clearly explained, this can't be done for inversify. If you want to have class parameter decorators please file issues in the tc39 proposal. Thanks.

PodaruDragos avatar Apr 18 '24 17:04 PodaruDragos

Isn't there any way to make it work like MobX? https://mobx.js.org/enabling-decorators.html

@injectable()
class Ninja {
    @inject(TYPES.Weapon) accessor katana: Weapon;
}

It should be possible by using only property injection with new accessor keyword.

Please re-open this as it is an ongoing problem for the future of Inversify.

murat-mehmet avatar Apr 18 '24 19:04 murat-mehmet

@murat-mehmet I don't mean to be rude, but, as said, it's not possible today. Inversify requires parameter decorators which are not standardized. If you really want us to reopen the issue, please, first consider having a look at the standard. Once you read the standard, you will notice there're not parameter decorators.

Stage 3 decorators would allow us to express:

@injectable()
class Ninja {
    @inject(TYPES.Weapon) public katana: Weapon;
}

But they do not allow us to express:

@injectable()
class Ninja {
    constructor(@inject(TYPES.Weapon) public katana: Weapon) {}
}

Because the second example demands parameter decorators.

Again, I would love to be mistaken and be able to get rid of legacy decorators. If so, I am more than happy to learn how to implement @inject in the second example, a parameter decorator, using stage 3 decorators so, if anybody knows a feasible technical approach, please feel free to share it here.

If https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#parameter-decorators-and-annotations is ever included in the standard, we will be able to go for it, but until that I would prefer to keep the issue closed.

I hope I made my point clear this time :smiley:

notaphplover avatar Apr 18 '24 23:04 notaphplover

@notaphplover Thanks for your detailed response. Actually, I'm sorry if I was rude :) I'm just rolling into a new large project and thinking about options here.

I understand that parameter decorators do not exist in the standard and there is an ongoing stage 1 proposal for it. However, it took more than 6 years to take decorators to stage 3, so I hardly believe parameter decorators will be here anytime soon.

In my previous answer, I was only looking for an option (maybe a special fork) that will support new decorators by removing constructor injection (and thus parameter decorators) completely from Inversify and use property injection instead. I know this is against the DI pattern, but in some cases staying up-to-date is a higher priority. I will take a look into it when I have some free time.

murat-mehmet avatar Apr 19 '24 08:04 murat-mehmet

@murat-mehmet

there is also a fork for this, @mscharley has done a great work supporting them. Of course it's not the same UX since that would be impossible. If you are curious check his repo

PodaruDragos avatar Apr 19 '24 10:04 PodaruDragos

Oh, hey thanks for the shout out! There's still some pretty big gaps in the documentation in places, especially getting started but if you're already familiar with Inversify it shouldn't be too hard to get started. If you have any questions then feel free to reach out in an issue. It's on a bit of a feature pause unless someone finds some bugs but the current implementation is strong enough that we've been using it for many months in production at my work so what is there is pretty solid.

mscharley avatar Apr 19 '24 11:04 mscharley