Mastersam07 / Mastersam07/kaisel
feat: let a route declare its result type so pop() and pushForResult<T>() are checked against each other
Nobody has claimed this yet.
- Dominant language
- Dart
- Stars
- 69
- Forks
- 2
- Avg merge
- 18m
- Merged PRs (30d)
- 9
Description
There is currently no type relationship between what a route pops and what its caller awaits.
`pushForResult(route)` declares what the **caller** expects. `pop([Object? result])` declares nothing about what the **route** produces. Neither is checked against the other:
```dart
// compiles cleanly; returns null (or throws) at runtime
router.pop(a string);
final wallet = await router.pushForResult(SelectWalletRoute());
```
auto_route had `pop(result)`, which at least typed the producing side. Migrating that to kaisel means **dropping** the only annotation that existed.
## Why migrations make this worse, not better
Routes that carry callbacks (`onComplete`, `onClose`, `onAction`) cannot survive as kaisel routes — routes are const value types with `props`, and a closure field breaks both const-ness and equality. The natural fix is to convert the callback into a popped result. That is the right move, but it means the number of result-carrying routes goes **up** during migration, on exactly the axis that has no type safety.
In one app this converted 13 routes from callback-carrying to result-returning. Every one of those is now an untyped contract between two files.
## `run` is not a general answer
`KaiselModalRoute` + `run` gives a real typed completion contract, but only for modal flows. A plain screen that returns a value — a picker, a filter sheet promoted to a full screen, a confirmation step — has no equivalent.
## Suggestion
Let a route declare its own result type:
```dart
abstract class KaiselResultRoute extends KaiselRoute {
const KaiselResultRoute();
}
final class SelectWallet extends AppRoute implements KaiselResultRoute {
const SelectWallet();
}
```
Then:
* `pushForResult` infers `T` from the route (`router.pushForResult(SelectWallet())` → `Future`),
* `pop` can be checked against the top routes declared type.
Failing that, a `pop(T result)` overload would at least restore parity with auto_route by typing the producing side.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading KaiselRoute, pushForResult, pop, and KaiselModalRoute/run, since the issue compares their current result contracts. Trace how a plain route and its caller communicate a result, then evaluate the proposed route-declared type against the typed pop fallback. Done means a non-modal route's produced result and the caller's awaited result are checked consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart, flutter
- Domain
- mobile-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100