The fact that futures implicitly "flatten" at runtime makes statically typing code that works with them harder. In some cases, code that accepts a Future<T> really effectively takes a Future<T>|T, which Dart cannot represent.
Strong mode currently has some ad hoc rules around Future.then() to make it work nicer, but those rules are kind of hacky and don't extend to user-defined methods that work in a similar fashion. See here and the following comments.
To finish off strong mode, we need to decide what the real rules we want here are, commit to them, and describe and implement them fully. A couple of options:
Async<T> which works roughly like a special case union type of Future<T>|T.馃憤 for Full-fledged union types.
I'd love Async<T> in the short term and full-fledged union types in the long term.
status: language team is ok with the Async<T> proposal (possibly with a different name). @lrhn is writing up the informal spec to be shared for wider feedback and then implementation.
We are going to implement FutureOr<T>: https://github.com/dart-lang/sdk/issues/28006
Most helpful comment
I'd love
Async<T>in the short term and full-fledged union types in the long term.