Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update inversify to fix TypeScript 5.0 errors #12425

Merged
merged 11 commits into from
May 26, 2023

Conversation

msujew
Copy link
Member

@msujew msujew commented Apr 17, 2023

What it does

With TypeScript 5.0, parameter checking for decorators has been made a bit stricter, which seems to clash with the type definitions of inversify@^5.0.0. inversify@^6.0.0 seems to resolve this. This is also related to eclipse-theia/generator-theia-extension#164.

How to test

The CI should be green.

Review checklist

Reminder for reviewers

@msujew msujew added the dependencies pull requests that update a dependency file label Apr 17, 2023
@msujew
Copy link
Member Author

msujew commented Apr 17, 2023

I've noticed a few issues with this PR. I'll put it on hold for now.

@msujew msujew marked this pull request as draft April 17, 2023 11:50
@msujew
Copy link
Member Author

msujew commented Apr 17, 2023

To explain the issues in more detail: We cannot inject promises into services with inversify 6. This isn't so bad, as we can easily work around this. However, services are now not allowed to contain promise fields at construction time. The following class can no longer be injected due to inversify incorrectly identifiying it as an "async class":

class InjectableService {
  constructor() {
    this.deferred = new Deferred(); // <-- This contains a promise, which makes this class only injectable in an async context.
  }
}

See also inversify/InversifyJS#1482 for more context.

@paul-marechal
Copy link
Member

paul-marechal commented Apr 17, 2023

Your code snippet wouldn't actually cause any issue with inversify@6. But there are definitely breaking changes when injecting promises. If the binding for an injection is a promise then Inversify will require that you resolve your component asynchronously.

Note that I encountered the same issue and opened a PR on Inversify: inversify/InversifyJS#1461

The reason I closed it is because it really feels like a DI anti-pattern to inject promises. When practising dependency injection you want to inject abstractions. Injecting a promise to an abstraction leads to problems such as handling delayed initialization of classes depending on promises that will eventually resolve. So Inversify went the route of "injecting a promise means we need to delay the initialization of your component until it resolves to the actual dependency that actually should be injected".

The quick fix for that specific issue would be to convert all bindings to promises into Inversify providers:

// before:
bind(OurPromiseApi).toConstantValue(thePromise);

// after:
bind(OurPromiseApi).toProvider(ctx => async () => thePromise);

Then we'll need to replace injection sites like this.ourPromiseApi.then() with this.ourPromiseApi().then().

@msujew
Copy link
Member Author

msujew commented Apr 18, 2023

@paul-marechal Yeah, you're right. I misinterpreted the error message that I got. The issue was with the async @postConstruct that we perform on a lot of services, not with the contained deferred promise.

@paul-marechal
Copy link
Member

paul-marechal commented Apr 18, 2023

Ah true, the async post constructors are also a problem when using inversify@6.

Related: #10788

@vince-fugnitto vince-fugnitto modified the milestone: 1.37.0 Apr 27, 2023
@msujew
Copy link
Member Author

msujew commented Apr 30, 2023

@paul-marechal This is ready for a review now. Note that I had to change something in the rpc-proxy mechanism, since Inversify thought that every proxy that we use as a dependency is in fact a Promise object, since it has a then function.

I'll add all the breaking changes after this gets an initial review. There are quite a few breaking changes in this PR, and I want a review on the general approach before documenting them all.

@msujew msujew marked this pull request as ready for review April 30, 2023 11:10
@paul-marechal
Copy link
Member

All that's missing now is an entry to the migration guide? Since we share our version of Inversify with downstream, their apps will break if they have async post constructors too.

@msujew
Copy link
Member Author

msujew commented May 3, 2023

@paul-marechal I've updated the migration guide and documented the breaking changes (at least everything that wasn't just init -> doInit) and will now go on vacation. For any outstanding comments, please provide the changes yourself. I trust you :)

Copy link
Member

@paul-marechal paul-marechal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change LGTM, will merge right after the upcoming release this week.

@paul-marechal
Copy link
Member

Just caught async dep issues on Electron and managed to fix them.

Please have one last look and merge if you don't find any other regressions/issues.

@msujew msujew merged commit c1a2b7b into master May 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies pull requests that update a dependency file
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants