void foo() {
final fooMap = {
'one': true,
};
bar(fooMap);
}
void bar(Map<String, Object> barMap) {
barMap['two'] = 'Hello World';
}
In the above code, I get the error:
DartError: TypeError: "Hello World": type 'String' is not a subtype of type 'bool'
As I understand it, this is because Map<String, bool>
is not a subtype of Map<String, Object>
. If my understanding is correct, I don’t know why my IDE doesn’t tell me not to do that.
In foo()
, if I change final fooMap...
to Map<String, Object> fooMap...
, then everything works just fine. But again, I feel like the IDE should catch it, to let me know about this.
In bar()
, if I copy the map into a new Map<String, Object>
, it also works.
My question is, how should I handle this? Is there a strongly typed option here? I prefer to catch things like this at compile time, not runtime.
6
Dart’s type inference is strong; the Map
s type will be inferred by its entries.
final map = {
'one': true,
};
is the same as
final Map<String, bool> map = {
'one': true,
};
You don’t get a compile error for the bar
function because technically, the map’s type of Map<String, bool>
compiles with the parameter’s type of Map<String, Object>
.
In Dart, as everything is of type Object
(except null
).
final one = true;
print(one is Object); // true
If you would like to allow dynamic
values on your map, you can go about it a couple different ways.
- (Recommended) Supply type arguments to the map
final map = <String, dynamic>{
'one': true,
};
- Add a second entry that differs from the first entries type
final map = {
'one': true,
'two': 'hello world',
};
Caution: This way only works because you are providing multiple value
s of different types.
If you provided multiple entries of the same types, the map’s inferred type wouldn’t change
// type: Map<String, bool>
final map = {
'one': true,
'two': false,
};