Why type inference is not able to infer a type in a function callback?
Your problem can be more clearly observed with:
class Foo<T> {
final void Function(T) bar;
Foo(T t, {required this.bar});
}
Type staticType<T>(T object) => T;
void main() {
var foo = Foo(0, bar: (x) => print(staticType(x)));
print(staticType(foo)); // Prints: Foo<int>
print(staticType(foo.bar)); // Prints: (int) => void
print(foo.bar.runtimeType); // Prints: (Object?) => void
foo.bar(42); // Prints: Object?
}
I'm not an expert on the inference rules (maybe lrn will provide a more authoritative and accurate explanation), but I believe that inference either can flow top-down (from function to arguments) or bottom-up (from arguments to function). Since you don't supply an explicit type parameter when constructing Foo
, Foo
's generic type argument T
must be inferred from its arguments. However, the argument type to the anonymous function also isn't specified, so it's assumed to be Object?
.
For Foo
's T
to be inferred as int
and for the anonymous function to be inferred to be (int) => void
would require inference to flow from the positional argument up to the function and back down to the named argument, which, to my understanding, Dart does not do. You thus instead end up with the (Object?) => void
anonymous function being implicitly cast to (int) => void
.