-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Invoking methods from abstract classes #47893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
You need to provide a more complete reproduction of the problem. I'd guess you did not properly instantiate the type somewhere so |
here is small example to produce the problem typedef Converters<ViewT, DataT> = FutureOr<DataT?> Function(ViewT? view);
abstract class AbstractControl<ViewT, DataT> {
late ViewT? initValue;
final Converters<ViewT?, DataT?> convertToData;
AbstractControl({this.initValue, required this.convertToData});
}
class Control<ViewT, DataT> extends AbstractControl<ViewT, DataT> {
Control({
ViewT? initValue,
required FutureOr<DataT?> Function(ViewT? val) convertToData,
}) : super(initValue: initValue, convertToData: convertToData);
}
main() {
final Map<String, AbstractControl> controls = {
"firstName": Control<String, String>(
initValue: "abc",
convertToData: (val) => val,
),
"lastName": Control<String, String>(
initValue: "xyz",
convertToData: (val) => "test + $val",
),
};
controls.forEach((key, control) {
final data = control.convertToData(control.initValue);
});
} while this works: import 'dart:async';
abstract class AbstractConverter<ViewT, DataT> {
FutureOr<DataT?> viewToData(ViewT? val);
}
class Converter<V, D> extends AbstractConverter<V, D> {
final FutureOr<D?> Function(V? val) converter;
Converter(this.converter);
@override
FutureOr<D?> viewToData(V? val) => converter(val);
}
abstract class AbstractControl<ViewT, DataT> {
late ViewT? initValue;
final Converter<ViewT?, DataT?> convertToData;
AbstractControl({this.initValue, required this.convertToData});
}
class Control<ViewT, DataT> extends AbstractControl<ViewT, DataT> {
Control({
ViewT? initValue,
required FutureOr<DataT?> Function(ViewT? val) convertToData,
}) : super(initValue: initValue, convertToData: Converter(convertToData));
}
main() {
final Map<String, AbstractControl> controls = {
"firstName": Control<String, String>(
initValue: "abc",
convertToData: (val) => val,
),
"lastName": Control<String, String>(
initValue: "xyz",
convertToData: (val) => "test + $val",
),
};
controls.forEach((key, control) {
final data = control.convertToData.viewToData(control.initValue);
print(data);
});
} |
Yeah this is a known problem. It is reduced to: class C<T> {
void Function(T) f;
C(this.f);
}
void main() {
C<dynamic> o = C<String>((String v) { });
o.f("smth"); // throws: type '(String) => Null' is not a subtype of type '(dynamic) => void'
} This is a corner case in the type-system: generics are covariant, but So void main() {
C<dynamic> o = C<String>((String v) { });
o.f("smth");
} is compiled as void main() {
C<dynamic> o = C<String>((String v) { });
(o.f as void Function(dynamic))("smth");
} Which should explain the error. See dart-lang/language#1137 for the deeper discussion. |
I'm using method from abstact class
typedef Converters<View, Data> = FutureOr<Data?> Function(View? view);
but after using it I receive for this example
type '(String?) => String?' is not a subtype of type '(dynamic) => dynamic'
why is this happening? For some reason I thought Dart 2.15 would solve this. Otherwise I need to replace typedef with abstract class and then extending with ordinary class which does work, but it makes code much more boilery, for exact same effect.
The text was updated successfully, but these errors were encountered: