Reputation: 9609
Consider the following code:
void printInt(int i) => print(i);
void printString(String s) => print(s);
void printSomething(Object o) {
final printer = {
int: printInt,
String: printString,
}[o.runtimeType];
print('Printer is $printer');
printer(o);
}
void main() => printSomething('Hello');
It prints the correct printString
function and then crashes with the following exception:
TypeError: "Hello": type 'String' is not a subtype of type 'Null'
Why does that happen?
Upvotes: 2
Views: 1157
Reputation: 31299
The error comes from the fact that your map has been given the type Map<Type, void Function(Null)>
since that is the only type it can use based on the content of you list.
The problem is that Dart cannot give your map another type since anything else would not be valid from the perspective of the type system. Let's say the type was Map<Type, void Function(Object)>
. Well, we are then allowed to send any object into a method from this map. But that is not allowed since your two methods in the map clearly are defined as accepting int
and String
and not Object
.
We can either give it the type Map<Type, void Function(int)>
since we have a method taking a String
.
Also, Map<Type, void Function(dynamic)>
has the same problem as Object
since both methods are clearly defined to taking a precise type.
So Dart will instead use Null
as the type of the parameter since the only thing we know is valid to give both methods are the null
value.
And since you are then trying to give a String
as parameter to a method with the signature of void Function(Null)
you are getting an error from the type system.
If you want you code to run, you need to tell the type system to keep quite about what you are doing. To do that, you should use dynamic
for the type of method you are receiving from the map:
void printInt(int i) => print(i);
void printString(String s) => print(s);
void printSomething(Object o) {
final dynamic printer = {
int: printInt,
String: printString,
}[o.runtimeType];
print('Printer is $printer');
printer(o);
}
void main() => printSomething('Hello');
Upvotes: 2