Skip to content

Conversation

@xephosbot
Copy link

The current implementation does not allow using koinEntryProvider when the backstack items type is not Any.
As a result, it’s necessary to manually cast the returned value:

NavDisplay(
    backStack = navigator.backStack, //List<MyNavKey>
    ...
    entryProvider = koinEntryProvider() as (MyNavKey) -> NavEntry<MyNavKey>
)

This PR removes that limitation and allows koinEntryProvider to work with typed backstack.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR makes the EntryProvider type and related functions generic to improve ergonomics when using typed navigation backstacks with Navigation3. Previously, users had to manually cast koinEntryProvider() when working with typed backstacks (e.g., List<MyNavKey>), which was verbose and error-prone. The changes add a generic type parameter <T : Any> throughout the API surface.

Key Changes:

  • Made EntryProvider typealias generic: EntryProvider<T> = (T) -> NavEntry<T>
  • Added generic type parameters to koinEntryProvider, Scope.getEntryProvider, and Android-specific extension functions
  • Added import for EntryProviderScope to support the cast needed for backward compatibility with the non-generic EntryProviderInstaller

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
projects/compose/koin-compose-navigation3/src/commonMain/kotlin/org/koin/compose/navigation3/EntryProvider.kt Core changes: made EntryProvider generic, added type parameters to functions, added cast to maintain compatibility with EntryProviderInstaller
projects/compose/koin-compose-navigation3/src/androidMain/kotlin/org/koin/androidx/compose/navigation3/ComponentCallbacksExt.kt Android-specific extensions updated with generic type parameters to match the core changes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

val entryProvider: (Any) -> NavEntry<Any> = entryProvider {
entries.forEach { builder -> this.builder() }
val entryProvider: EntryProvider<T> = entryProvider {
entries.forEach { builder -> (this as EntryProviderScope<Any>).builder() }
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The unsafe cast to EntryProviderScope<Any> is necessary due to the design where EntryProviderInstaller is hardcoded to EntryProviderScope<Any>. While this works because the navigation3 library's type-safe entry<T> calls handle type matching at registration time, it means that the generic type parameter T on koinEntryProvider<T>() doesn't actually provide compile-time type safety - it only affects the return type signature.

This could be misleading to API consumers who might expect that calling koinEntryProvider<MyNavKey>() would restrict entries to only those registered for MyNavKey. Consider adding a KDoc note explaining that T is a convenience type parameter for the caller's type system and doesn't enforce which entries are included at runtime.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants