Dart Map Key Type Safety

Viewed 1757

I've implemented enums as keys for my maps, but I'm finding that Dart doesn't provide type safety when retrieving values.

For example, the following code does not cause compilations errors:

enum Animal {Bird, Cat, Dog, Horse}

Map<Animal, String> petNames = {
  Animal.Bird: 'Lucky',
  Animal.Cat: 'Cleo',
  Animal.Dog: 'Spot',
  Animal.Horse: 'Sleven',
};

String birdName = petNames[Animal.Bird]; // Positive test
String catName = petNames[1]; // What I want to test
String dogName = petNames['two']; // My control, I expected a compilation error

print(birdName); // Output as expected: Lucky
print(catName); // Output is null
print(dogName); // Output is null

Is this a defect in Dart?

1 Answers

No, its not a bug. Here you can check what are you calling when you execute something like petNames[1] or petNames['two']. Internally, Dart takes the value inside square brackets as an Object because you are using the [] operator.

When you check the Map definition, you can see that is defined as a Generic Type (with parameters K and V). For example when you assign some value to some key on that map:

petNames[Animal.Bird] = 'New Bird Name'

You are using the operator []= and that operator call a function isValidKey() to check if the key (Animal.Bird in the example) is of type K (Animal) and the value ('New Bird Name' in the example) is of type V (String).

But isValidKey() function is not called when you use the [] operator.

So, as in Dart all is an Object, and the [] operator get as input an Object, when you call petNames['two'], Dart will try to find that key, even if it is not of type K.

For more information please check the links above and this issue on Dart Lang SDK.

Related