avoid_future_of_option
This rule flags a function or method returning Future<Option<T>>, which TaskOption<T> already expresses.
Why use this rule
Section titled “Why use this rule”The Option counterpart of avoid_future_of_either, and the same argument.
Future<Option<T>> is correct but throws away composition: a caller has to await before it can flatMap, so every chain leaves the fpdart world and comes back. And because a Future starts running the moment it is created, the work is already under way by the time anyone holds it — it cannot be retried, delayed, or built up now and run later.
TaskOption<T> is the type that already means “async computation that may find nothing”, and it stays lazy until .run().
Future<Option<User>> findUser(String id) async { return Option.fromNullable(await cache.get(id));}TaskOption<User> findUser(String id) => TaskOption(() async => Option.fromNullable(await cache.get(id)));Known limitations
Section titled “Known limitations”FutureOr<Option<T>> is not reported: it may complete synchronously, so it is a different shape with a different answer.
A generator (Stream<Option<T>> with async*) is never reported — one TaskOption cannot stand in for a stream of values.
The reverse nesting, Option<Future<T>>, belongs to avoid_either_of_future, which covers both synchronous wrappers.
Related assist
Section titled “Related assist”No quick fix is offered: the conversion changes a public signature, so every call site needs updating and an “apply all” would leave the project uncompilable.
There is an assist. Put the cursor on the function and pick “Convert to TaskOption” — it rewrites the signature and moves the body into a TaskOption. See Assists.
Options
Section titled “Options”many_lints: rules: avoid_future_of_option: ignore_private: truerules: avoid_future_of_option: ignore_private: true| Option | Type | Default | Description |
|---|---|---|---|
ignore_private |
bool | false |
Skip private functions and methods |
Configuration
Section titled “Configuration”This rule is in the opinionated preset. With a lower preset, enable it by
name with avoid_future_of_option: true.
To turn it off:
rules: avoid_future_of_option: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_either_of_future— A Future nested in Either or Option escapes the error channel.avoid_future_of_either— Future<Either> throws away the composition TaskEither already gives you.prefer_task_either_over_try_catch— A repository’s failures belong in its signature, not in a try/catch.avoid_unnecessary_option— An Option that is wrapped and immediately unwrapped earns nothing.